Why We Need Address Calculation
A 2D array looks like a grid on paper, but computer memory is one-dimensional — a long line of bytes. To access arr[i][j], the compiler must calculate exactly which byte in that line holds the value. This calculation depends on whether the array is stored in Row-Major Order or Column-Major Order.
- C uses Row-Major Order — all of row 0 is stored first, then row 1, then row 2
- Fortran uses Column-Major Order — all of column 0 first, then column 1...
- Knowing this determines which loops are faster and how to compute addresses
To access an element of a two-dimensional array, you must specify the index number of both the row and column. For example, matrix[0][2] accesses the value in the first row (0) and third column (2).
/* Accessing a 2D array element */ int matrix[2][3] = { {1, 4, 2}, {3, 6, 8} }; printf("%d", matrix[0][2]); /* Outputs 2 — row 0, col 2 */ printf("%d", matrix[1][1]); /* Outputs 6 — row 1, col 1 */
Row-Major Order — C Default
In Row-Major Order, the array arr[x][y] is stored row by row in memory. When you move from one element to the next, you go across the current row before jumping to the next row.
Address of arr[i][j] = Base Address + (i × y + j) × size where: i = row index j = column index y = total number of COLUMNS in the array size = bytes per element (int=4, float=4, char=1, double=8)
int arr[3][4] stored in memory — row by row (each int = 4 bytes)
Column-Major Order
In Column-Major Order, the array is stored column by column. All elements of column 0 are stored first, then column 1, etc. The formula changes — now you multiply j by the number of rows (not columns).
Address of arr[i][j] = Base Address + (j × x + i) × size where: i = row index j = column index x = total number of ROWS in the array size = bytes per element
Row-major: multiply i by COLUMNS →
(i × COLS + j) × sizeColumn-major: multiply j by ROWS →
(j × ROWS + i) × sizeIn C, always use row-major. Column-major appears only in exam questions asking you to compare.
| Array | Element | Base | Size | Row-Major | Col-Major |
|---|---|---|---|---|---|
| arr[6][8] | arr[3][4] | 200 | 4 | 312 | 308 |
| arr[7][6] | arr[5][3] | 500 | 4 | 632 | 604 |
| arr[4][10] | arr[2][7] | 1000 | 4 | 1108 | 1120 |
| arr[5][8] | arr[4][5] | 2000 | 8 | 2296 | 2232 |
C Program — Verify Address Calculations
#include <stdio.h> int main() { int arr[4][10]; long base, offset; int i, j; base = (long)&arr[0][0]; printf("Base address (arr[0][0]) = %ld\n\n", base); printf("%-12s %-14s %-12s\n", "Element", "Actual Addr", "Offset"); printf("--------------------------------------\n"); /* Print first 3 rows */ for (i = 0; i < 3; i++) { for (j = 0; j < 4; j++) { offset = (long)&arr[i][j] - base; printf("arr[%d][%d] %ld +%ld\n", i, j, (long)&arr[i][j], offset); } } /* Verify formula for arr[2][7] */ printf("\n--- Verify Example R3 ---\n"); printf("Formula: base + (2*10+7)*4 = base + %d\n", ((2*10)+7)*4); printf("Actual: arr[2][7] offset = +%ld\n", (long)&arr[2][7] - base); printf("Match: %s\n", ((2*10+7)*4 == (long)&arr[2][7]-base) ? "YES" : "NO"); return 0; }
Base address (arr[0][0]) = 1000 (example) Element Actual Addr Offset -------------------------------------- arr[0][0] 1000 +0 arr[0][1] 1004 +4 arr[0][2] 1008 +8 arr[0][3] 1012 +12 arr[1][0] 1016 +16 ← row 1 starts at +40 (4 cols × 4 bytes) arr[1][1] 1020 +20 arr[2][0] 1040 +40 ← row 2 starts at +80 arr[2][7] 1108 +108 --- Verify Example R3 --- Formula: base + (2*10+7)*4 = base + 108 Actual: arr[2][7] offset = +108 Match: YES
Address Calculation Quiz
In Row-Major order, find address of arr[2][3] in array arr[5][5]. Base=300, int=4 bytes.
In Column-Major order, find address of arr[2][3] in array arr[5][5]. Base=300, int=4 bytes.
For double arr[6][8], base=4000. What is the address of arr[3][5] in row-major? (double=8 bytes)
C uses Row-Major order. Which loop order is FASTER for processing a 2D array row by row?
Checklist
- I know C stores 2D arrays in Row-Major order (row by row)
- Row-Major formula: Base + (i × COLS + j) × size
- Column-Major formula: Base + (j × ROWS + i) × size
- I can identify i=row, j=col, y=total cols, x=total rows, size=bytes per type
- I completed all 8 worked examples and got the same answers
- I completed the quiz