Различные способы передачи двумерного массива указателя в функцию C - PullRequest
0 голосов
/ 14 декабря 2010

Я столкнулся с некоторыми проблемами при передаче 2d-массива в функции сегодня, позже я нашел некоторые решения, такие как A и B. Я знал, что 2d-массив хранится в непрерывной памяти как 1d. Так что, на мой взгляд, на самом деле нет двухмерных точек, компилятор разделил эти непрерывные числа и создал «двумерную» концепцию.

У меня такой вопрос: в C после того, как я явно сказал компилятору, параметр является int **, почему он не прошел 2-мерную точку?

Кто-то может указать, что "в C вы не указали компилятору длину группы", я думаю, что он знал эту информацию, потому что если вы попытаетесь повторно объяснить простую память из 12 элементов в arr [2] [6], это будет ошибка типа "void printArr (int _arr [] [6], int _columns, int _rows)".

Немного смущен, пожалуйста, помогите ...

int arr[][3]={{1,2,3},{5,6,7},{9,10,11},{13,14,15}};

void printArr(int _arr[][3], int _columns, int _rows){ //----->A
void printArr(int (* _arr)[3], int _columns, int _rows){//---->B
void printArr(int** _arr, int _columns, int _rows){//--------->C
    for(int r=0; r< _rows; r++){
        for (int c=0; c<_columns; c++)
            //printf("%4d,", _arr[r][c]);
            printf("%4d,", *(*(_arr+r)+c));
    }   
}
int main(){
    printArr(arr, columns, rows);
}

Ответы [ 4 ]

2 голосов
/ 14 декабря 2010

Массивы распадаются на указатели, это означает, что если у вас есть массив массивов int arr[x][y], он может распадаться на указатель на массив int (*arr)[y].

int ** arr, следовательно, будет версией распавшегося массивауказатели int *arr[x], которые несовместимы с вашим массивом.

0 голосов
/ 17 декабря 2010

Вы правы, что компилятор резервирует непрерывный блок памяти, зная, что вы можете сделать что-то вроде моего примера.Он также работает с 1d массивами, то есть: printArr ((int *) arr, 1, 10);

void printArr(int *_arr, int _columns, int _rows) {
    for(int r = 0; r < _rows; r++) {
        for (int c = 0; c < _columns; c++) {
            printf("%4d,", _arr[r * _columns + c]);
        }
    }   
}

int arr[][3]={{1,2,3},{5,6,7},{9,10,11},{13,14,15}};
printArr((int*)arr, 3, 4);

Я думаю, что вы были очень близки с C. Два изменения параметризуются с помощью int *, а неint ** и ваш расчет смещения был неверным.

0 голосов
/ 14 декабря 2010

Примечание о стиле: не используйте начальные подчеркивания для ваших идентификаторов;такие имена зарезервированы для реализации.

Решение B явно фиксирует происходящее;в вызове printArr выражение arr неявно преобразуется из "массива из 4 элементов массива из 3 элементов типа int" в "указатель на массив из 3 элементов типа int".

Однако в контексте объявления параметра функции нотация T a[] является синонимом T *a;следовательно, решение A фактически совпадает с решением B.

0 голосов
/ 14 декабря 2010

int ** - указатель на указатель на int, а не указатель на 2-мерный массив.

...