C ++: новый, вопрос понимания памяти - PullRequest
1 голос
/ 01 июля 2010

почему это не работает:

Фрагмент 1:

int *a = new int[6];
(*a)[0]=1;

пока это работает

Фрагмент 2:

int myint = 0;
int *ptr = &myint;
*ptr=1;

Я знаю, что если я использую a[0]=1 в фрагменте 1, это будет работать. Но для меня это не имеет смысла, потому что для меня это выглядит так, что a[0]=1 означает: установите значение 1 для адреса [0]. Другими словами, я ставлю значение как память. Вместо этого имеет больше смысла использовать (*a)[0]=1, что означает для меня: поместите значение 1 в поле значения, на которое указывает [0].

Может ли кто-нибудь описать это несоответствие?

Ответы [ 4 ]

11 голосов
/ 01 июля 2010

Фрагмент 1 должен быть:

int *a = new int[6];
a[0]=1;

Это потому, что a[0] эквивалентно *(a+0).

1 голос
/ 01 июля 2010

Оператор индексирования [] имеет встроенный оператор *. Итак, первый фрагмент в основном делает это:

int *a = new int[6];
*((*a) + 0) = 1;

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

1 голос
/ 01 июля 2010

Это неоднозначно , если указатель указывает на массив или отдельный элемент.

(*a) разыменовывает первый (или, возможно, единственный) элемент.

a[0] разыменовывает первый элемент.

a[1] явно обрабатывает указатель как массив и разыменовывает второй элемент. Программист должен убедиться, что такой элемент существует.

1 голос
/ 01 июля 2010

Вы должны просто использовать * a not (* a) [0].

Помните, «а» - указатель. Указатель - это адрес.

*a = a[0] or the first integer
*(a + 1) = a[1] or the second integer

'a' не является указателем на массив. Это указатель на целое число. Таким образом, * a не возвращает вам массив для работы с [].

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

Рассмотрим следующее:

int x = 10;

Этот фрагмент объявляет целое число x и присваивает ему значение 10. Теперь рассмотрим это:

int *y = &x;

Этот фрагмент объявляет, что y является указателем на целое число, и назначает адрес x для y.

Вы могли бы написать это так:

int x = 10;
int *y;

y = &x;

Кстати, когда вы назначаете что-то для 'y' выше, оно просто берет данные по этому адресу и превращает их в целое число. Итак, если вы отправите его в массив char (8 бит или 1 байт каждый), а целое число будет длиной 32 бита (4 байта) в вашей системе, тогда он просто возьмет первые четыре символа массива char и преобразует результирующее 32-битное число в целое число.

Остерегайтесь указателей, здесь есть драконы.

...