How to pass 2D array (matrix) in a function in C?
Mia Lopez
I need to do this to persist operations on the matrix as well. Does that mean that it needs to be passed by reference?
Will this suffice?
void operate_on_matrix(char matrix[][20]);
4 Answers
C does not really have multi-dimensional arrays, but there are several ways to simulate them. The way to pass such arrays to a function depends on the way used to simulate the multiple dimensions:
1) Use an array of arrays. This can only be used if your array bounds are fully determined at compile time, or if your compiler supports VLA's:
#define ROWS 4
#define COLS 5
void func(int array[ROWS][COLS])
{ int i, j; for (i=0; i<ROWS; i++) { for (j=0; j<COLS; j++) { array[i][j] = i*j; } }
}
void func_vla(int rows, int cols, int array[rows][cols])
{ int i, j; for (i=0; i<rows; i++) { for (j=0; j<cols; j++) { array[i][j] = i*j; } }
}
int main()
{ int x[ROWS][COLS]; func(x); func_vla(ROWS, COLS, x);
}2) Use a (dynamically allocated) array of pointers to (dynamically allocated) arrays. This is used mostly when the array bounds are not known until runtime.
void func(int** array, int rows, int cols)
{ int i, j; for (i=0; i<rows; i++) { for (j=0; j<cols; j++) { array[i][j] = i*j; } }
}
int main()
{ int rows, cols, i; int **x; /* obtain values for rows & cols */ /* allocate the array */ x = malloc(rows * sizeof *x); for (i=0; i<rows; i++) { x[i] = malloc(cols * sizeof *x[i]); } /* use the array */ func(x, rows, cols); /* deallocate the array */ for (i=0; i<rows; i++) { free(x[i]); } free(x);
}3) Use a 1-dimensional array and fixup the indices. This can be used with both statically allocated (fixed-size) and dynamically allocated arrays:
void func(int* array, int rows, int cols)
{ int i, j; for (i=0; i<rows; i++) { for (j=0; j<cols; j++) { array[i*cols+j]=i*j; } }
}
int main()
{ int rows, cols; int *x; /* obtain values for rows & cols */ /* allocate the array */ x = malloc(rows * cols * sizeof *x); /* use the array */ func(x, rows, cols); /* deallocate the array */ free(x);
}4) Use a dynamically allocated VLA. One advantage of this over option 2 is that there is a single memory allocation; another is that less memory is needed because the array of pointers is not required.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
extern void func_vla(int rows, int cols, int array[rows][cols]);
extern void get_rows_cols(int *rows, int *cols);
extern void dump_array(const char *tag, int rows, int cols, int array[rows][cols]);
void func_vla(int rows, int cols, int array[rows][cols])
{ for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { array[i][j] = (i + 1) * (j + 1); } }
}
int main(void)
{ int rows, cols; get_rows_cols(&rows, &cols); int (*array)[cols] = malloc(rows * cols * sizeof(array[0][0])); /* error check omitted */ func_vla(rows, cols, array); dump_array("After initialization", rows, cols, array); free(array); return 0;
}
void dump_array(const char *tag, int rows, int cols, int array[rows][cols])
{ printf("%s (%dx%d):\n", tag, rows, cols); for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) printf("%4d", array[i][j]); putchar('\n'); }
}
void get_rows_cols(int *rows, int *cols)
{ srand(time(0)); // Only acceptable because it is called once *rows = 5 + rand() % 10; *cols = 3 + rand() % 12;
}(See srand() — why call it only once?.)
Easiest Way in Passing A Variable-Length 2D Array
Most clean technique for both C & C++ is: pass 2D array like a 1D array, then use as 2D inside the function.
#include <stdio.h>
void func(int row, int col, int* matrix){ int i, j; for(i=0; i<row; i++){ for(j=0; j<col; j++){ printf("%d ", *(matrix + i*col + j)); // or better: printf("%d ", *matrix++); } printf("\n"); }
}
int main(){ int matrix[2][3] = { {0, 1, 2}, {3, 4, 5} }; func(2, 3, matrix[0]); return 0;
}Internally, no matter how many dimensions an array has, C/C++ always maintains a 1D array. And so, we can pass any multi-dimensional array like this.
10I don't know what you mean by "data dont get lost". Here's how you pass a normal 2D array to a function:
void myfunc(int arr[M][N]) { // M is optional, but N is required ..
}
int main() { int somearr[M][N]; ... myfunc(somearr); ...
} 5 2D array:
int sum(int array[][COLS], int rows)
{
}3D array:
int sum(int array[][B][C], int A)
{
}4D array:
int sum(int array[][B][C][D], int A)
{
}and nD array:
int sum(int ar[][B][C][D][E][F].....[N], int A)
{
}