Может кто-нибудь разъяснить мне эту идею массива / указателя? - PullRequest
5 голосов
/ 21 ноября 2011

Пытаясь объяснить, что массивы являются просто указателями (в C ++) для нашего класса, мой профессор показал нам это:

array[5]      // cout'ing this 
*(array + 5)  // would return the same value as this

У меня небольшая проблема с полным пониманием этого. Вот мое мышление:

array - это адрес первого местоположения, поэтому, если мы добавим 5 к этому адресу, мы переместим 5 адресов в памяти. Оператор-указатель извлекает данные из ячейки памяти.

Это правильная идея? Идея все еще кажется мне туманной, и я просто не понимаю ее полностью. Я думаю, что услышав, что кто-то еще объяснит, это могло бы помочь мне понять это больше. Заранее спасибо!

Ответы [ 4 ]

4 голосов
/ 21 ноября 2011

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

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

Например, рассмотрим этот код:

int array[5];
int * pointer = new int[5];
cout << sizeof(array);   // outputs 5*sizeof(int), most probably 20
cout << sizeof(pointer); // outputs sizeof(int*), most probably 4 on a 32 bit OS
array[4] = 906;
pointer[4] = 906;
cout << *(array + 4) << *(pointer + 4); // outputs "906 906"
4 голосов
/ 21 ноября 2011

У вас правильная идея.

Массивы неявно приводятся к указателям. Интересно, что [] работает с указателями, а не с массивами.

a [b] Оператор подписи определен как *(a + (b)). [] используется как синтаксический сахар - гораздо приятнее писать array[5] вместо *(array + 5)

Арифметика указателя с указателем и целым числом p + i увеличивает адрес на p на i * sizeof(*p) байт.

char* p; 
p + 5; // address increased by 5

int* p;
p + 5; // address increased by 20 as sizeof(*p) is 4

Оператор * выполняет косвенное обращение. Это даст вам то, на что указывает указатель.

int x[2];
int* p = &x[0]; // could also be int* p = x;
*p = 5;         // x[0] is now 5
*(p + 1) = 10;  // x[1] is now 10
2 голосов
/ 21 ноября 2011

Да, то, что сказал ваш профессор, правильно.

для подробного объяснения

Рассмотрим ваш массив,

int array[5]

здесь требуется 5 позиций в памяти, скажем 0x00 0x04 0x08 0x0C и 0x10 0x14

Предполагается, что целое число занимает 4 байта, местоположения на расстоянии 4 байта.

в этом случае «массив» представляет базовый адрес (указатель) на массив, то есть 0x00.И типом будет int *.(поскольку тип элементов массива целочисленный)

Если вы сделаете массив + 1, он будет 0x04, поскольку приращение указателя зависит от типа указателя.Если указатель целочисленный, он будет увеличиваться на 4 байта.Если тип целого числа символьный, указатель будет увеличиваться на один байт.

поэтому, если вы сделаете (массив + 5), он будет указывать на адрес 0x14, а

*(array+5)

возвращает значение местоположения 0x14, которое является значением в 5-м расположении массива.

, поэтому на практике массив [5] равен * (массив + 5)

Компилятор внутренне преобразует массив [5] в * (массив + 5)

, поэтомудаже если мы напишем 5 [массив], он будет преобразован в * (5 + массив)

Хотя это кажется странным, поэтому 5 [массив] работает так же, как массив [5]

2 голосов
/ 21 ноября 2011

из массивов памяти в c ++ - это разделы непрерывной памяти программы. вот почему вы можете пойти * (массив + 5), так как это 5 от начала массива.

Также имейте в виду, что массивы в C ++ начинаются с @ 0, поэтому 6-й элемент массива - это массив [5] Пример

[0] [1] [2] [3] [4] [5] Array index
 1   2   3   4   5   6  Item number

Для доступа к пункту 2 вы либо

  • массив [1]
  • * (массив + 1)

, но имейте в виду, что массив [index_number] - это стандартный синтаксис для поиска элемента в массиве, поэтому убедитесь, что вы используете array[index_num] вместо *(array + index_num)

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