Since a 2D array is an array of arrays, you can think of it as a 1D array, where every row of the 2D array follows each other:
int array2D[4][2] = { { 11, 12 }, { 21, 22 }, { 31, 32 }, { 41, 42 } };
int array1D[8] = { 11, 12, 21, 22, 31, 32, 41, 42 };
Why is it good? Because you don't have to mind do you allocate a 1D or a 2D array, the key is how you index it. Here is my example:
#include <stdio.h>
#include <stdlib.h>
#define COL_NUM 2
int main() {
int rows = 5;
// allocate a 1D array, with size: rows * columns
int* array = (int*)calloc(rows * COL_NUM, sizeof(int));
// fill the array with some values
int i, j = 0;
for(i = 0; i < rows; ++i) {
array[i * COL_NUM + j] = 1; // index elements as if it were 2D array
j = (j + 1) % COL_NUM;
}
// print the quasi 2D array
for(i = 0; i < rows; ++i) {
for(j = 0; j < COL_NUM; ++j)
printf("%d ", array[i * COL_NUM + j]);
printf("\n");
}
free(array);
return 0;
}
As in the example above, indexing a 1D array as if it were 2D array explained by the following:
#define NUMBER_OF_COLUMNS 2
int row = 2, column = 0;
array2D[row][column] = 5;
array1D[row * NUMBER_OF_COLUMNS + column] = 5;
As the comments below warn, indexing a 1D array as if it were a 2D array (with the method shown above) is safe, but the opposite is undefined behavior. My previous statement:
Since a 2D array is an array of arrays, you can think of it as a 1D array
shouldn't be understood as you can indexing a 2D array as if it were a 1D array.