comma , is an operator just like + evaluating a + b: evaluate a and b in any order, result made by adding those two sub-results evaluating a, b: evalute a first, evaluate b second, result is the second sub-result. int x; x = 12, 3 + x, 99 * w, 5; means 12, 3+x, and 99*w are evaluated but ignored, x becomes 5 for (int i = 1; i < 7; i += 1) ... for (int i = 1, j = 9; i < 7; i += 1) ... for (int i = 1, j = 9; i < 7 && j > 2; i += 1) ... for (int i = 1, j = 9; i < 7 && j > 2; i += 1, j -= 1) ... also allowed: y + 7; z == 3; any expression (thing that produces a result) can become a statement (thing that makes something happen) just by adding a semi-colon to it. also assignments = and updates += *= etc are expressions so they can be used in ifs and couts and on the right of an assignment sign =. cout << "i = " << i << "\n"; if (i = 3) cout << "it's three\n"; order of evaluation x += f(5) * 2 y += f(5) + f(3) * f(7); functions used in expressions as here (i.e. non-void functions) ideally should not make changes to anything, they should just return the appropriate value. Otherwise the last example above has an unpredictable value. Priority rules tell us that f(3) * f(7) will be worked out then its result will be added to f(5), but nothing tells us which order f(5), f(3), and f(7) will be evaluated in. For clarity, let's split that into four statements, using temporary variables t1 to hold f(5), t2 to hold f(3), and t3 to hold f(7). We know that the fourth line must be y += t1 + t2 * t3 and that t1 will be multiplied by t2 before the result is incremented by t3, but the rules of C++ allow the whole thing to be any of these 6 possibilities: t1 = f(5); t2 = f(3); t3 = f(7); y += t1 + t2 * t3 t1 = f(5); t3 = f(7); t2 = f(3); y += t1 + t2 * t3 t2 = f(3); t1 = f(5); t3 = f(7); y += t1 + t2 * t3 t2 = f(3); t3 = f(7); t1 = f(5); y += t1 + t2 * t3 t3 = f(7); t1 = f(5); t2 = f(3); y += t1 + t2 * t3 t3 = f(7); t2 = f(3); t1 = f(5); y += t1 + t2 * t3 and if f changes anything that it uses, they will have different results. a function call statement is really just a function call expression folloewd by a semi-colon. f(5); ; alone is also a statement, it does nothing, except causing hard to catch errors. while (i == 3); { i += 1; j = k * 3; ... the rules for if are also trouble if (a == 3) if (b == 4) cout << "X\n"; else cout << "Y\n"; multi-dimensional arrays int A[4][3][5]; XXXXX wrong int A[4, 3, 5]; in memory it occupies 4*3*5 * 4 consecutive bytes in exactly this order: (the last * 4 is because of 4 bytes in an int) A[0][0][0] A[0][0][1] A[0][0][2] A[0][0][3] A[0][0][4] A[0][1][0] A[0][1][1] A[0][1][2] A[0][1][3] A[0][1][4] A[0][2][0] A[0][2][1] A[0][2][2] A[0][2][3] A[0][2][4] A[1][0][0] A[1][0][1] ... ... A[3][1][3] A[3][1][4] A[3][2][0] A[3][2][1] A[3][2][2] A[3][2][3] A[3][2][4] where is A[i][j][k] ? know i, j, k, and where A begins given int A[4][3][5]; A[i][j][k] is at position A + i * 3 * 5 + j * 5 + k in memory must know all of A, i, 3, 5, j, k to find A[i][j][k] to pass A (or other 3d array) to function ... void f(int R[][3][5]) { ... ... as a parameter must specify all dimensions except first more bad design: you may also specify the first dimension but what you say will be ignored, probably leading you to false assumptions. alternate implementation, array of pointers to arrays of pointers to arrays ... int * * * A; A = new int * * [4]; for (int i = 0; i < 4; i += 1) { A[i] = new int * [3]; for (int j = 0; j < 3; j += 1) { A[i][j] = new int[5]; // optional initialisation loo: for (int k = 0; k < 5; k += 1) A[i][j][k] = i * 100 + j * 10 + k; } } an implementation specific to three-dimensional arrays iof ints: class array { protected: int size[3]; int * data; public: array(int s0, int s1, int s2) { size[0] = s0; size[1] = s1; size[2] = s2; data = new int[s1 * s2 * s3]; } int & at(int i, int j, int k) { assert(i >= 0 && i < size[0]); assert(j >= 0 && j < size[1]); assert(k >= 0 && k < size[2]); return data[i * size[1] * size[2] + j * size[2] + k]; } int size(int dim) { assert(dim >= 0 && dim < 3); return size[dim]; } ~array() { delete [] data; } }; want to be able to write int f(array & r) { ... } needs stdarg (sample posted separately) Why should arrays have to start at position 0? Imagine recording a data item for every month of every year from 2000 to 2099. Declare like this: double info[2100][13]; could access like this info[y][m] e.g. info[2025][2] += 1 to increment entry for Feb 2025 but a lot of wasted space or declare like thisL double info[100][12]; must remember to offset indexes as in info[y - 2000][m - 1]; far too easy to forget or use wrong number. In olden days we could have written double info[2000:2099][1:12]; just for accuracy, in the first language to support this, Algol-60 it would have been real array info[2000:2099, 1:12];