2013-03-06 2 views
1

Я пытаюсь передать 2D-массив функции. Я попробовал другое решение в Интернете.Разница между разностью массивов

int arr[3][4]; 
fun (arr); 



1) void fun(int *a[4]) {} -- result into a compilation error (cannot convert int (*)[4] to int **) 

2) void fun(int(*a)[4]) {} -- works fine. 

Я хочу знать, в чем разница между двумя вышеуказанными декларациями и тем, что есть ошибка в 1. случае.

+0

Измените свой код, это не C или C++! –

+1

'int arr [3] [4]' будет вырождаться в 'int *', а не 'int **'! –

+0

Один из них принимает массив указателей 'int' (размер теряется во время распада), а другой - указатель на массив' int' из четырех значений. Они совсем разные звери. – WhozCraig

ответ

0
  1. int* a[4] представляет собой массив из 4 int* с
  2. int (*a)[4] представляет собой указатель на массив 4 int с

Имя массива может быть преобразован в указатель на его первый элемент. То есть arr, так как это имя int[3][4], будет преобразовано в указатель на первый элемент arr, который сам является int[4]. Этот тип - int(*)[4]. Вот почему вы можете пройти arr во втором случае.

В C++, вы можете передать ссылку на полный массив так:

void fun(int(&a)[3][4]) {} 

В этом случае не происходит массива к указателю преобразования. Вы просто берете ссылку на 2D-массив.

0

int *a[4] представляет собой массив из 4 указателей на int, тогда как int(*a)[4] представляет собой указатель на массив 4 int.

Так как массив распадается на указатель на его первый элемент (до тех пор, как он не используется в качестве операнда &, sizeof или _Alignof), a[3][4] будут преобразованы в (*a)[4].

5

Ну, вот то, что когда-либо полезным cdecl говорит об этом:

  • int *a[4] означает «объявить как массив 4 указателя Int»
  • int(*a)[4] означает «объявить как указатель на массив 4 ИНТ»
+1

ОК, что взгляд пород. – WhozCraig

+0

Спасибо за ссылку. Может быть полезно! – Joze

+0

Но в объявлении параметра функции 'int * a [4]' означает declare 'a' как указатель на указатель на' int'. Это важно в контексте вопроса. –

1

Это объявляет массив из 4 указателей на целые:

int* a[4];  // (a) 

Это, с другой стороны:

int (*a)[4]; // (b) 

Объявляет указатель на массив целых чисел 4.

Так как массивы распадаются на указатели (к их первому элементу), при использовании в качестве аргументов функции, передавая объект типа int arr[3][4] в функцию, которая принимает параметр типа (б) выше будут успешные (разлагающиеся к указателю int[4], то есть int (*)[4]), в то время как он не работает, когда тип параметра (a).

0

исключения случаев, когда это операнд sizeof, _Alignof или одинарных & операторов, или является строкой символов используются для инициализации другого массива в объявлении, выражения типа «N-элемент массив T» будет преобразован в выражение типа «указатель на T», а значение выражения будет адресом первого элемента в массиве.

В вызове функции

fun(arr); 

тип выражения arr является "3-элемент массива из 4-элемента массива int". Так как arr не является операндом операторов sizeof, _Alignof или унарных &, он преобразуется в выражение типа «указатель на 4-элементный массив int», который записывается как int (*arr)[4], а его значением будет адрес от a[0].

Постфиксные операторы, такие как [] и () имеют более высокий приоритет, чем унарные операторы, как *, так *a[N] является N -элементного массив указателей, в то время как (*a)[N] является указатель на N -элементный массив. Аналогично, *f() - это функция, возвращающая указатель, а (*f)() - указатель на функцию.

Смежные вопросы