(gcc) Multi-Dim Array или Double Pointer для компиляции без предупреждения - PullRequest
0 голосов
/ 26 марта 2010

У меня есть функция, которая иногда вызывается с обычными, иногда динамическими массивами.

Если я определю функцию как

function_name(int[10][10] a)

и отправка int ** в качестве параметра, я получаю предупреждение. Напротив, если я объявлю

function_name(int** a)

и отправить int [] [] в качестве параметра (после приведения) Я не могу получить доступ к элементам массива внутри функции.

Что такое правильный путь?

Ответы [ 2 ]

1 голос
/ 26 марта 2010

Когда массив передается функции, он «распадается» на указатель на свой первый элемент. Итак, учитывая:

T a[10];
f(a);

В вызове f(a), a фактически является &a[0], то есть указателем, а тип является T * (тип &a[0]).

Когда у вас есть массив массивов, применяется то же правило:

T a[10][5];
f(a);

a снова распадается на указатель, равный &a[0]. a[0] имеет тип "массив [5] из T". Таким образом, &a[0] имеет тип «указатель на массив [5] из T», то есть, если бы вы объявили указатель p для установки равным &a[0], вы должны сделать:

T (*p)[5]; /* parentheses because [] binds tighter than * */
p = &a[0];

Учитывая вышеизложенное и предполагая, что ваш массив объявлен в вызывающем коде как int a[10][10];, вы должны объявить свою функцию как:

function_name(int (*a)[10]);

Подробнее см. this .

Синтаксическая ошибка в function_name(int[10][10] a) - вам необходимо указать размер массива после имени «переменной»: function_name(int a[10][10]). Фактически, вышесказанное эквивалентно function_name(int (*a)[10]) из-за упомянутого выше «распада».

Редактировать : ах, думаю, теперь я понимаю. Вы не можете объявить функцию, которая принимает как «двумерный» массив, так и указатель на указатель по причинам, указанным выше («распад» на указатель происходит только один раз). Указатель на указатель может не указывать на смежные данные и может иметь разное количество элементов в каждой «строке». Массив массивов не может иметь эти свойства. Они принципиально разные.

1 голос
/ 26 марта 2010

int ** и int [][] не совпадают. Первый - pointer to pointer to int, а второй - двумерный массив int.

int[][] затухает до int (*)[] при передаче его в качестве аргумента функции.

void func(int arr[][10]) { //decays to `int (*arr)[10]` 
  printf("%d correct", arr[1][9]); //10th element of 2nd row
  //printf("%d correct", (*(arr + 1))[9]); //same as above
}

int main() {
  int (*arr)[10]; //pointer to array of ints
  arr = malloc(sizeof(int (*)[]) * 2); //2 rows & malloc will do implicit cast.

  arr[1][9] = 19;
  func(arr);

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