Передача многомерных массивов в качестве аргументов функции в C - PullRequest
49 голосов
/ 07 августа 2008

Могу ли я передать в C многомерный массив функции в качестве единственного аргумента, когда я не знаю, какими будут размеры этого массива?

Кроме того, мой многомерный массив может содержать типы, отличные от строк.

Ответы [ 4 ]

31 голосов
/ 16 декабря 2009

Передайте явный указатель на первый элемент с размерами массива в качестве отдельных параметров. Например, для обработки двухмерных массивов произвольных размеров типа int:

void func_2d(int *p, size_t M, size_t N)
{
  size_t i, j;
  ...
  p[i*N+j] = ...;
}

который будет называться

...
int arr1[10][20];
int arr2[5][80];
...
func_2d(&arr1[0][0], 10, 20);
func_2d(&arr2[0][0], 5, 80);

Тот же принцип применяется для массивов более высокой размерности:

func_3d(int *p, size_t X, size_t Y, size_t Z)
{
  size_t i, j, k;
  ...
  p[i*Y*Z+j*Z+k] = ...;
  ...
}
...
arr2[10][20][30];
...
func_3d(&arr[0][0][0], 10, 20, 30);
19 голосов
/ 07 августа 2008

Вы можете сделать это с любым типом данных. Просто сделайте указатель на указатель:

typedef struct {
  int myint;
  char* mystring;
} data;

data** array;

Но не забывайте, что вы все равно должны распределять переменную malloc, и она становится немного сложной:

//initialize
int x,y,w,h;
w = 10; //width of array
h = 20; //height of array

//malloc the 'y' dimension
array = malloc(sizeof(data*) * h);

//iterate over 'y' dimension
for(y=0;y<h;y++){
  //malloc the 'x' dimension
  array[y] = malloc(sizeof(data) * w);

  //iterate over the 'x' dimension
  for(x=0;x<w;x++){
    //malloc the string in the data structure
    array[y][x].mystring = malloc(50); //50 chars

    //initialize
    array[y][x].myint = 6;
    strcpy(array[y][x].mystring, "w00t");
  }
}

Код для освобождения структуры выглядит аналогично - не забывайте вызывать free () для всего, что у вас есть. (Также в надежных приложениях вы должны проверить возврат malloc () .)

Теперь предположим, что вы хотите передать это функции. Вы все еще можете использовать двойной указатель, потому что вы, вероятно, хотите делать манипуляции со структурой данных, а не указатель на указатели структур данных:

int whatsMyInt(data** arrayPtr, int x, int y){
  return arrayPtr[y][x].myint;
}

Вызовите эту функцию с помощью:

printf("My int is %d.\n", whatsMyInt(array, 2, 4));

Выход:

My int is 6.
18 голосов
/ 08 июля 2014

Вы можете объявить свою функцию как:

f(int size, int data[][size]) {...}

Затем компилятор выполнит всю арифметику с указателями.

Обратите внимание, что размеры размеров должны отображаться до самого массива.

GNU C позволяет переадресацию объявления аргумента (в случае, если вам действительно нужно передать измерения после массива):

f(int size; int data[][size], int size) {...}

Первое измерение, хотя вы также можете передавать его в качестве аргумента, бесполезно для компилятора C (даже для оператора sizeof, когда он применяется к массиву, передаваемому в качестве аргумента, всегда будет указывать на первый элемент).

0 голосов
/ 03 января 2012
int matmax(int **p, int dim) // p- matrix , dim- dimension of the matrix 
{
    return p[0][0];  
}

int main()
{
   int *u[5]; // will be a 5x5 matrix

   for(int i = 0; i < 5; i++)
       u[i] = new int[5];

   u[0][0] = 1; // initialize u[0][0] - not mandatory

   // put data in u[][]

   printf("%d", matmax(u, 0)); //call to function
   getche(); // just to see the result
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...