Przekazywanie tablic wielowymiarowych jako argumentów funkcji w C

W C Czy mogę przekazać tablicę wielowymiarową do funkcji jako pojedynczy argument, gdy nie wiem jakie będą wymiary tablicy ?

DODATKOWO moja tablica wielowymiarowa może zawierać typy inne niż łańcuchy.

 47
c
Author: David, 2008-08-07

4 answers

Możesz to zrobić z dowolnym typem danych. Po prostu zrób z tego wskaźnik-do-wskaźnika:

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

data** array;

Ale nie zapominaj, że nadal musisz malloc zmiennej, a to robi się trochę skomplikowane:

//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");
  }
}

Kod deallocate struktury wygląda podobnie - nie zapomnij wywołać free() na wszystko, co malloced! (Również, w solidnych aplikacjach powinieneś sprawdzić zwrot malloc () .)

Teraz powiedzmy, że chcesz przekazać to do funkcji. Nadal możesz używać podwójnego wskaźnika, ponieważ prawdopodobnie chcesz manipulować strukturą danych, a nie wskaźnikiem do wskaźników struktur danych:

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

Wywołanie tej funkcji przez:

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

Wyjście:

My int is 6.
 19
Author: andrewrk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-29 23:38:48

Przekazuje jawny wskaźnik do pierwszego elementu z wymiarami tablicy jako oddzielnymi parametrami. Na przykład, aby obsłużyć dowolnie wielkości tablice 2-d int:

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

Które można by nazwać

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

Ta sama zasada dotyczy tablic wyższych wymiarów:

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);
 31
Author: John Bode,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-26 18:42:17

Możesz zadeklarować swoją funkcję jako:

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

Kompilator wykona za Ciebie całą arytmetykę wskaźnika.

Zauważ, że rozmiary wymiarów muszą pojawić się przed samą tablicą.

GNU C pozwala na przekazywanie deklaracji argumentów (w przypadku, gdy naprawdę trzeba przekazać wymiary po tablicy):

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

Pierwszy wymiar, chociaż można przekazać jako argument, jest bezużyteczny dla kompilatora C (nawet dla operatora sizeof, gdy jest stosowany nad tablicą przekazywaną jako argument będzie zawsze traktował is jako wskaźnik do pierwszego elementu).

 15
Author: rslemos,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-12 18:51:34
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
}
 -2
Author: Pedro,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-07 17:37:07