2016-11-15 11 views
3

Я узнал, что имя массива на самом деле является адресом array_name[0]. Тогда почему требуется добавить знак амперсанда перед именем массива при инициализации указателя на массив.Инициализация указателя на массив

int (*pointer_name)[5] = &array_name; 

Я пробовал:

int *pointer_name = array_name; 

и она отлично работает. В чем разница между двумя, кроме «типа указателя»? А также какие плюсы-минусы любого из них. Когда их использовать? У кого-нибудь из них есть какая-либо большая/лучшая функциональность над другими?

+0

«Я узнал, что имя массива на самом деле является адресом array_name [0]». Вы учились неправильно. Имя массива может * действовать как * (* притворяться *) указателем на 'array_name [0]' в определенных контекстах, но не во всех контекстах. И вы определенно не можете сказать, что имя массива * - это адрес 'array_name [0]'. – AnT

ответ

2

Тогда почему требуется добавить знак амперсанда [..]. Я попытался: int * pointer_name = имя_базы; И он отлично работает.

Потому что типы различны.

  • &array_name представляет собой указатель на массив из 5 целых чисел и имеет тип: int (*)[5].

  • array_name преобразуется в указатель на его первый элемент, когда вы назначаете его pointer_name (что эквивалентно &array_name[0]) и имеет вид: int*.

Если array_name массив из 5 целых чисел, то оба:

int (*pointer_name)[5] = &array_name; 

и

int *pointer_name = array_name; 

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

+0

Я проверил. Оба типа указателя имеют размер = 8 байт. И сохраненное ими значение тоже самое. Какая разница между двумя. Являются ли они одинаковыми по функциональности? –

+0

Адрес будет таким же ('& array_name == & array_name [0] == array_name'). Но как вы можете получить доступ к этому массиву. С 'int * pointer_name = array_name;' вы можете получить к нему доступ, например: 'pointer_name [0]/* имя_мастера [0] * /' или '* имя_поиска/* имя_архива [0] * /; * (pointer_name + 1)/* имя_архива [1] */'. С 'int (* pointer_name) [5] = & array_name;', вы можете получить к нему доступ, как: '(* pointer_name) [1];/* array_name [1] */'. Оба способа в порядке. Но основное отличие заключается в том, как арифметика указателя работает над этими типами. – usr

3
int *pointer_name = array_name; 

объявляет указатель на int, что указывает на первый int массива array_name.

int (*pointer_name)[5] = &array_name; 

объявляет указатель на массив 5 int с, что указывает на массив array_name.

Адреса такие же, но не типа.

При использовании арифметики указателей на тех, у вас есть, в первом случае:

pointer_name++; 

будет только указать на второй int массива, в то время как во втором случае будет указывать только после того, как в целом массив.

0

Тип объекта, на который указывает указатель объявлен как

int (*pointer_name)[5] = &array_name; 

является int[5]. Это означает, например, что этот оператор

sizeof(*pointer_name) 

дает значение, равное 5 * sizeof(int). И что если использовать арифметику указателя, например, pointer_name + 1, то адрес, полученный этим выражением, будет равен адресу, сохраненному в указателе плюс значение 5 * sizeof(int).

Тип объекта, на который указывает указатель объявлен как

int *pointer_name = array_name; 

является int. Это означает, например, что этот оператор

sizeof(*pointer_name) 

дает значение, равное sizeof(int). И что если использовать арифметику указателя, например, pointer_name + 1, то адрес, полученный этим выражением, будет равен адресу, сохраненному в указателе плюс значение sizeof(int).

указатель объявлен как этот

int (*pointer_name)[5]; 

обычно используется для двумерных массивов, что указывает на «строки» из массива.

Например

int array_name[2][5]; 

int (*pointer_name)[5] = array_name; 

// outputs 20 provided that sizeof(int) is equal to 4 
printf("%zu\n", sizeof(*pointer_name)); 

// outputs 4 provided that sizeof(int) is equal to 4 
printf("%zu\n", sizeof(**pointer_name)); 

pointer_name указывает на первой строке массива array_name. pointer_name + 1 указывает на вторую строку массива.

+0

Во второй строке фрагмента кода над ним, который не использовал знак амперсанда перед именем «array_name». Почему здесь не требуется адресный оператор. А также кто-то упомянул об этом в комментариях, что «И вы определенно не можете сказать, что имя массива является адресом array_name [0],« почему это так? –

+0

@ShawAnkush Я не понял, что вы просите. Если вы имеете в виду этот фрагмент кода int array_name [2] [5]; int (* pointer_name) [5] = имя_базы; , тогда не требуется амперсанд. –

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