Как работают указатели на указатели и адрес оператора? - PullRequest
6 голосов
/ 06 октября 2010

Возьмите этот кусок кода:

int a;
int *pointer = &a;

int **b = &(&(*pointer));

Будет ли приведенный выше набор b по адресу pointer или нет?

Причина, по которой я спрашиваю, заключается в том, что *pointerдает значение a, а ссылка на него является адресом a.Это рассматривается как просто адрес a или также pointer.

Имеет ли это смысл?Могу ли я сделать:

&(*pointer) = a;

Ответы [ 6 ]

7 голосов
/ 06 октября 2010

Нет. В C вы можете получить только указатель на область хранения (что означает переменную, элемент массива или другой указатель; они называют эти «l-значения»), но не на любое выражение. Вы не можете получить указатель на выражения, которые не имеют определенной области хранения (например, сложение или результат вызова функции). Следует отметить, однако, что C ++ смешивает эти правила со ссылками, но для ясности я опущу это.

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

Например, если вы получите указатель на a в своем коде, вы просто копируете этот адрес в другую переменную. Ничто не мешает вам изменить указанную переменную:

int a;
int* p = &a;
p = NULL;

И делая это, вы a останетесь неизменными. Все, что вы можете изменить о a, это его значение. Его адрес неизменен. Все остальное подразумевало бы, что &a = NULL (или любое другое значение указателя) будет работать, а это не так.

3 голосов
/ 06 октября 2010

int ** b = & (& (* указатель));

Это не или не должно компилироваться.

Вы можете взять только адрес l-значения. (См. Описание ниже)

C ++ 03 S5.3.1-2:

Результат унарного оператора & указатель на его операнд. Операнд должен быть lvalue или квалифицированным. В первом случае, если тип выражение «Т», тип Результатом является «указатель на T.» В в частности, адрес объекта типа «cv T» является «указатель на cv T» с такими же cv-квалификаторами. Для квалифицированный идентификатор, если участник является статический член типа «Т», тип результат - «указатель на T». Если член является нестатическим членом класс C типа T, тип Результатом является «указатель на член класса C типа


... и это ссылка на адрес ...

Также здесь вы используете неверный термин. & является символом, который используется для разных вещей. одна из таких вещей заключается в объявлении ссылок, несвязанной вещью является адрес унарного оператора. Последнее не называется ссылкой.


Имеет ли это смысл? Могу ли я сделать: &(*pointer) = a;

Адрес переменной, и, следовательно, &(*pointer) или эквивалентно &a являются r-значениями.

Вы не можете ничего присвоить r-avlue. Игнорируя такие вещи, как const, вы можете считать r-значение чем-то, что должно появляться справа. Значение l похоже на левую часть, но на самом деле это означает, что оно может быть сохранено в месте хранения (разница в том, что, например, const-объект не может появиться на левой стороне, но он все еще считается l- значение).

1 голос
/ 06 октября 2010

Вы не можете взять адрес чего-либо дважды, поэтому приведенный выше код, вероятно, даже не скомпилируется (вы пробовали это? Что случилось?).

0 голосов
/ 06 октября 2010

1.Нет, и это приводит к ошибке компиляции при int **b = &(&(*pointer));
2. Установите b по адресу указателя: int **b = &pointer;
3. &(*pointer) = a; -> НЕТ, ты не можешь. &something константа не может быть изменена, должна быть *pointer = a; или pointer = &a;

0 голосов
/ 06 октября 2010

Будет ли приведенное выше значение b указывать на адрес указателя или нет?

Нет, не будет.&(*pointer) - это адрес a, который представляет собой просто число (значение r), и вы не можете взять адрес или присвоить значение r.Таким образом, и &(&(*pointer)), и &(*pointer) = a не будут компилироваться.

Адрес pointer просто &pointer, поэтому то, что будет работать, будет int **b = &pointer;.

0 голосов
/ 06 октября 2010

В вашем выражении:

* ptr является lvalue & (* ptr) является значением

& (& (* ptr)) является неправильно сформированным выражением, поскольку вы пытаетесь получить адрес значения r, недопустимого в C ++.

Кроме того,

& (* указатель) = a;

плохо сформирован, потому что тип выражения lhs - int *, где тип выражения rhs - int. C ++ не позволяет преобразовывать int в int

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