There is a common misconception about column major vs row major arrays that I see often as a teaching assistant. If I ask a question such as "Arrays in C are:"

(a) Always column major
(b) Always row major
(c) Either column major or row major depending on how they are declared
(d) Neither column major nor row major

I will frequently have students insist that (c) is a correct answer. They will say "Suppose I have a table with 2 columns and 4 rows I could declare it as int table[2][4]; and treat the first index as the column index and the second index as the row index. Using this column major array my program would run just fine."

They are correct their program would run just fine, but their table array is still row major. Here is why.

Column major and row major have nothing to do with the way you think about an array. Sure you could immagine that the first subscript refers to a column number. You are just rotating the array in your head. However column major and row major have a more formal definition:

Suppose we have a two dimentional array like int A[3][3] We can think of the array A like this:

          A11 A12 A13
          A21 A22 A23
          A31 A32 A33

The array A must be stored in memory. This causes a problem. There is no such thing as two dimentional memory. Main memory is just like a big 1D array with indices from 0x0 to 0Xffffff. So somehow we have to place our 2D array into 1D memory. Since we want all the locations in an array to be contiguous we have two logical choices for how to line them up. We can store the elements in memory like this:

|           A11 A21 A31 A12 A22 A32 A13 A23 A33          |
|                                                        |
0x0                --> Higher Addresses                  0xffffff

This is FORTRAN's column major order, the first array index varies most rapidly.


The other option is to line them up like this:

|           A11 A12 A13 A21 A22 A23 A31 A32 A33          |
|                                                        |
0x0                --> Higher Addresses                  0xffffff

This is C's row major order, the last array index varies most rapidly.

The difference lies in how they are stored in memory not in how you interpret the memory.