Its been like 2 years since ive been programming. There is this question that is bothering me lately and its kind of silly. but i seriously need an answer.
When i code for some difficult programs, I try to form a skeleton logic and write on paper. Then i code it and if the output is not correct, i make changes in the program based on a rough judgement of what might have gone wrong (like change '<' to '<=' or change 'variable++' to '++variable' and some tweaks here and there). sometimes i wont have any idea of what im doing but i give it a try to see if it works.
but i am now worried if this is a bad way to program..I mean is it compulsory that a programmer should have complete idea of what he is coding? is guessing what might have gone wrong and changing code just to try your luck a bad practice?
Yes, it does look a bad way to program, I am afraid.
It is not compulsory to have a good idea before you start out; the compiler will happily let you program something which produces the wrong result. Changing < to <= or i++ to ++i suggests you are making potentially dangerous out‑by‑one errors, and you really need to learn to get the logic correct on paper before you put finger to keyboard.
If you are confused between ++i and i++, you ought to avoid using them as parts of other expressions. Only use them on their own, in which case you would use i++ exclusively (by convention only).
There are conventional forms for control structures. For example we conventionally use for (int i = 0; i < arr.length; i++)
} Even the spacing is set conventionally. There is a good reason for that. Not only does it make the loop easier to read, but also it guarantees to take an array of any size and traverse it correctly without out of bounds exceptions. Following standard practices will reduce the risk of errors.
Start with a good design. Update the design documents regularly. Create additional design documents before adding major new features or functionality.
The program under development should be at all times functioning. The development process consists of adding new functionality without breaking existing functionality.
Work has to be divided into small incremental steps that can be typically accomplished and code-reviewed in one day. Even large-scale rewrites should be made incremental.
Every line of code written or modified undergoes peer review. The smallest team must contain at least two programmers so that they can code-review each other's changes.
Always attempt to work top-down in:
Design—start with high level objects.
Implementation—create top-level objects using low-level stubs.
Modification—change the top-level objects and the overall flow of control first. If necessary, use stubs, or fake new functionality using old implementation.
An "ideal" or a god-like programmer would have a complete idea of how each line of code in a particular program behaves. His/Her mind would work like Google Maps. S/he would be able to mentally zoom all the way out and have a clear picture of how all the system interconnect, and at the same time be instantly zoom in to any particular piece and be able to tell in detail what each piece of code will behave under every possible condition
However, none of us have god-like powers. Which is why we build code modularly, and we document the code. We break down the problem into digestible pieces that can fit neatly in our puny minds and we focus on building a module at a time. Usually, when a programmer tells me that s/he is spending time tweaking his code to handle "edge cases", it indicates to me that s/he hasn't broken down the problem well enough. Also, it's important to use consistent constructs throughout the code. Taking Ivan's example above, if you consistently use for(int i=0; i<lenght; i++) in your code, next time you read the code, you don't need to mentally parse the for statement. Your brain hits the for statement and fills in the details.
As a side note, since a mentioned a god-like programmer, IMO, God would make a lousy programmer However, Jesus does save, she He has that going for him :p
You should really know what you're doing before you write your "for" loop e.g. when it should stop looping, and how to implement that in a standard way. Personally, I never use the pre-increment operator (++i) for anything.
More generally, you shouldn't really start coding something until you understand what you're trying to achieve. That's part of the motivation for Test-Driven Development (TDD): by writing the tests first, you are forced to think about what you want your code to do before you write it. It's not fool-proof, but it does help make sure you know what you're trying to do.
Also, if you want to get some ideas on how to improve your coding, try the book "Clean Code" by Robert C. Martin ("Uncle Bob"), which has lots of good advice.