Я хотел знать, есть ли альтернативные способы присвоения указателю адреса значения, на которое он указывает. Например, есть обычный способ:

int a = 10;
int *ptr;
ptr = &a;

Но в некоторых местах я вижу, что это объявлено так:

int *ptr = &a;

Оба эти способа эквивалентны? Я немного сбит с толку, потому что всегда считал, что * ptr дает значение a, а не адрес. Может ли кто-нибудь объяснить? Спасибо.

6
QPTR 7 Янв 2016 в 14:56

5 ответов

Лучший ответ

Я немного сбит с толку, потому что я всегда считал *ptr значением a, а не адресом.

Это действительно немного сбивает с толку, поскольку * используется для объявления указателя, а также используется как оператор разыменования. Фактическое значение * зависит от контекста - используется ли он в объявлении, инициализации или присваивании.

Стоит знать разницу между 1) объявлением, 2) инициализацией и 3) присваиванием.

int *ptr; // 1) this is declaration without initialisation.

int *ptr = &a; // 2) this is declaration **and** initialisation (initialise ptr to the address of variable a)

int b = 10;
*ptr = b;   // 3) this is assignment, assign what pointed by ptr to value of variable b.
  • В 1) * означает, что ptr является указателем на int (но он еще не указал на какое-либо допустимое местоположение).
  • В 2) * означает, что ptr является указателем на int, а его начальное значение - это адрес переменной a.
  • В 3) * является оператором разыменования, т. Е. Присваивает то, что указано ptr, значению переменной b.
9
artm 2 Дек 2016 в 21:40

Если во время объявления используется оператор *, то он просто используется для указания типа объявляемой переменной. Тогда как во всех остальных случаях оператор * используется как оператор разыменования (кроме случаев, когда он используется как оператор умножения).

Итак, int *ptr = &a означает ptr переменную типа int *, которой был присвоен &a

А *ptr = a означает variable stored at address ptr (разыменование ptr), которому присваивается a.

1
rootkea 7 Янв 2016 в 12:22

Оба эти способа эквивалентны?

Да.

Второй вариант предпочтительнее, так как первый оставляет ptr неназначенным до последней строки (хотя на практике компилятор, вероятно, оптимизирует это).

Я немного сбит с толку, потому что я всегда считал * ptr значением a, а не адресом.

Вы путаете синтаксис объявления переменной с синтаксисом использования этой переменной.

int *ptr;

Просто объявляет переменную с именем ptr, которая является указателем на целое число.

int *ptr = &a;

Делает то же самое. Первая часть - это по-прежнему просто объявление указателя, как и раньше. Часть после знака равенства инициализирует ptr адресом a

Вы правы, что после объявления, когда вы позже будете использовать эту переменную в последующем коде, указав *ptr, вы получите содержимое указателя (в данном случае значение a).

2
GrahamS 7 Янв 2016 в 12:11

int *ptr; ptr = &a; для int *ptr = &a;, как int n; n = 3; для int n = 3;.

То есть объявление и инициализация указателя ничем не отличается от обычных переменных. Я предпочитаю использовать одну строку, когда это возможно, поскольку в этом случае меньше опасность наличия неинициализированных переменных.

2
Bathsheba 7 Янв 2016 в 12:00

Нет .. это объявление и инициализация в одной строке.

Это проясняет идею ..

typedef int* intp;

intp ptr=&a;

Эквивалентно

intp ptr; //int *ptr;
ptr=&a;   // ptr=&a;

Ответ: ДА, они эквивалентны.

Вы можете спросить- : - Как компилятор понимает? (является ли * косвенным или указанным в объявлении)

Ответ: - C зависит от контекста .. компилятор принимает решение на основе контекста, в котором он используется.

2
user2736738 7 Янв 2016 в 12:08