2008-08-06 6 views
45

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

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

ответ

19

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

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

data** array; 

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

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

Код для освобождения структура выглядит аналогично - не забудьте позвонить бесплатно() на все, что вы malloced! (Кроме того, в надежных приложениях вы должны check the return of 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. 
+0

Помощь нужна здесь: http: //stackoverflow.com/questions/16943909/manipulate-multidimensional-array-in-a-function – Dchris 2013-06-05 16:01:25

+3

Указатель на сегментированную таблицу поиска указателя не является двумерным массивом. Просто потому, что он позволяет синтаксис `[] []`, он не волшебным образом превращается в массив.Вы не можете memcpy() и т. Д., Потому что память не выделяется в смежных ячейках памяти, что требуется для массивов. Ваша таблица поиска довольно разбросана по всей куче, делая поиск медленным, а куча фрагментирована. – Lundin 2015-06-23 10:42:37

31

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

`p [i * Y + j * Z + k]` вместо этого должно быть `p [i * Y * Z + j * Z + k ]`. – 2012-08-18 09:01:38

+0

http://stackoverflow.com/questions/16943909/manipulate-multidimensional-array-in-a-function – Dchris 2013-06-05 16:02:08

-2
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 
} 
15

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

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

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

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

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

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

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