如何传递2D 数组(矩阵)在一个函数在 C?

我需要这样做来保持矩阵上的操作。这是否意味着它需要通过引用传递?

这样够了吗?

void operate_on_matrix(char matrix[][20]);

294349 次浏览

I 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);
...
}

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?.)

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)
{


}

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.