The main function returns an integer. The integer returned is a status value that is sent back to the operating system. Status 0 means that all went well. A nonzero status indicates that an error occurred.
Typically, the main program looks like this.
int main() { Your main program body return 0; }
Here is an example of a main program. It reads a number n from the user and prints a table of the squares from 1 to n. It uses manipulator setw to set the number of characters to use for each number. To use them, you must include <iomanip.h>.
int main() { int n,k; cin >> n; k = 1; while(k <= n) { cout << setw(4) << k << setw(9) << k*k << endl; } return 0; }
You write a simple function like this.
return-type name (parameters) { computational instructions return return-value; }The return-type is the type of the result. For example, the return-type of the sqrt function is double. The name is the name of the function. Each parameter in the parameter list consists of a type and a name for the parameter, in that order. If there are two or more parameters, they are separated by commas.
For example, here is a function that takes in a real number (type double) and returns the square of that real number. If it is given 5.0, it returns 25.0.
double sqr(double x) { return x*x; }
Here is a function that returns the maximum of two integers.
int max(int a, int b) { int result; if(a > b) { result = a; } else { result = b; } return result; }
The maximum finding function can be written in a shorter form. Here it is.
int max(int a, int b) { if(a > b) return a; else return b; }
Add 1 to s |
Add 2 to s |
Add 3 to s |
... |
Add n to s |
There is a problem with this. A while loop will do one thing over and over. But the lines that we have so far keep changing; no two of them are exactly the same. There first says to add 1 to s, the second says to add 2 to s, etc. We need a variable to hold the value to be added. Let's call that variable k. We will set k = 1 initially. Then the actions to be performed are
Add k to s |
Add 1 to k |
Add k to s |
Add 1 to k |
Add k to s |
Add 1 to k |
... |
Add k to s (where k is n at this line) |
Add 1 to k |
Now we see exactly the same thing over and over. We just repeat
Add k to s |
Add 1 to k |
int addup(int n) { int k,s; s = 0; k = 1; while(k <= n) { s = s + k; k = k + 1; } return s; }
To see what is going on, we make a table showing two variables. One variable holds the partial sum, and the other tells how much of the sum we have.
k | s | |
0 | 0 | |
1 | 1 (= 0 + 1) | |
2 | 3 (= 0 + 1 + 2) | |
3 | 6 (= 0 + 1 + 2 + 3) | |
4 | 10 (= 0 + 1 + 2 + 3 + 4) | |
... | ||
n | 0 + 1 + 2 + 3 + ... + n |
Now we are ready to think about writing the loop. Clearly, we need two variables, k and s. Each should have initial value 0 (given by the first line of the table). The loop should stop when k == n, so it should only keep going as long as k != n.
What about updating the values of k and n, going from one line to the next? To get from
k | s | |
2 | 3 (= 0 + 1 + 2) |
k | s | |
3 | 6 (= 0 + 1 + 2 + 3) |
int addup(int n) { int k,s; k = 0; s = 0; while(k != n) { k = k + 1; s = s + k; } }
s = 1 + 2 + ... + kFor example, when s = 3 and k = 2, the assertion is true. When s = 10 and k = 4 the assertion is true. No matter what line of the table you choose, the assertion is true. Since this assertion is true at every line, it is invariantly true. It is therefore called a loop invariant.
A loop invariant is a kind of assertion. We will use a special, technical definition of the word assertion. An assertion is a statement that is true or false, and is based solely on the current values of variables. Think of taking a snapshot of the variables at a certain point in the program. An assertion can only talk about what is seen in the snapshot. It cannot talk about what happened before or after the snapshot. For example, if i and j are variables, then
i > jis an assertion, since whether it is true or false depends only on the current values of i and j. On the other hand,
1 has been added to iis not an assertion, since this statement is trying to relate the current value of i to a former value of i.
When you try to write a loop invariant, make sure that your loop invariant is an assertion.
In some situations, action-oriented loop design is simple and natural. If you see how to solve a problem using action-oriented design, use that. In more complex situations, you can find it difficult to think of the actions to perform. In those cases, switch to data-oriented loop design. It will often lead you in the right direction.
Experience by professional programmers has shown that data-oriented loop design combined with loop invariants is more reliable, and tends to lead to correct programs more often than action-oriented design.