Передача многомерных массивов в качестве аргументов функции в C

StackOverflow https://stackoverflow.com/questions/4051

  •  08-06-2019
  •  | 
  •  

Вопрос

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

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

Это было полезно?

Решение

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

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.

Другие советы

Передайте явный указатель на первый элемент с размерами массива в качестве отдельных параметров.Например, для обработки двумерных массивов произвольного размера типа 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);

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

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

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

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

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

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

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

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
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top