Передача 2D массива указателей в C - PullRequest
1 голос
/ 09 апреля 2011

Для моей программы мне нужно передать двумерный массив указателей на функцию в отдельном файле.Я написал файл с аналогичным синтаксисом ниже:

#include <stdlib.h>
#include <stdio.h>

typedef struct {
  int state;
  int design;
} card_t;

card_t *cardSet[5][5];

void setFirst(card_t *cards[][]) { // <- Error: Array has incomplete element type
  cards[0][0]->state = 1;
}

int main() {
  setFirst(cardSet);  // <- Error: Type of formal parameter 1 is incomplete
  return 0;
}

Когда я изменяю код на все 1D-массивы, он прекрасно компилируется, но для 2D-массива я получаю ошибки, показанные выше.В чем разница между двумя делами?

Спасибо!Cameron

Ответы [ 4 ]

1 голос
/ 09 апреля 2011

Как уже упоминалось, для передачи двумерного массива в функцию вам необходимо иметь каждое измерение, кроме первого , объявленного.Тем не менее, вы также можете просто передать указатель, как показано ниже.Обратите внимание, что вы всегда должны (если измерение массива не является полностью фиксированным, а функция, которая работает с массивом, работает только в измерении массива), также передавать длину каждого массива.через code[0][0] то же самое, что и *(*(code+0)+0*m), вы можете передать два указателя вместо размеров массива.

1 голос
/ 09 апреля 2011

если вы передаете массив функции, вы должны указать размер внутреннего массива, в вашем случае вместо void setFirst(card_t *cards[][]) вы должны указать void setFirst(card_t *cards[][5]).

Почему нужно указывать его, а не размер первого измерения?

Так как cards - это массив массив указателей card_t, если вы хотите получить карты [1] [0], компилятору нужно будет знать, сколько добавить к указателю cards - объявлены карты: card_t *cards[5][4] потребуется добавить 4 * sizeof(*card_t), чтобы попасть на карты [1] [0], но если карты объявлены: card_t *cards[5][5], то для добавления на карты [1] [0] потребуется добавить 5 * sizeof(*card_t).

0 голосов
/ 09 апреля 2011

Для достижения чего-то похожего на то, что вы пытаетесь, в C99 есть массивы переменной длины.Они особенно полезны в определениях функций:

void setFirst(size_t n, size_t m, card_t *cards[n][m]) {
...
}

Обратите внимание, что у вас должны быть параметры размера, известные на момент объявления массива, поэтому вы должны поместить их впереди.

0 голосов
/ 09 апреля 2011

Только первый индекс не является обязательным. Вы должны обязательно упомянуть второй индекс, потому что двумерный массив распадается на указатель на 1d массив.

void setFirst(card_t *cards[][5]) {
                           // ^ Newly added

 // ..

}

Также убедитесь, что указатели указывают на допустимые области памяти. Остальное разыменование приводит к ошибкам сегментации. Кстати, есть ли причина иметь двумерный массив с указателями. Я думаю, вы просто усложняете программу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...