Что означают * и & применительно к именам переменных?

В С++, в чем разница между:

 void func(MyType&); // declaration

 //...
 MyType * ptr;

 func(*ptr); // compiler doesnt give error

 func(ptr); // compiler gives error i thought & represents memory address so 
            // this statement should correct as ptr is only a pointer
            // or address of some real var.

person PUG    schedule 28.07.2010    source источник
comment
Вы должны получить книгу, которая научит вас правильно. (И лучше, чем мы.)   -  person GManNickG    schedule 28.07.2010


Ответы (1)


Унарный префиксный оператор & при применении к объекту дает адрес объекта: &obj.< br> модификатор типа & при применении к переменной, которую нужно объявить, изменит тип переменной на ссылочный тип: int&.

То же самое относится и к *: при применении к указателю в качестве оператора унарного префикса он разыменовывает указатель. , возвращая объект, на который ссылается: *ptr.
При использовании в качестве модификатора типа для переменной, которую нужно объявить, * изменит тип на модификатор типа >указатель: int*.

Аналогичным образом, модификатор типа [], примененный к объявляемой переменной, изменит тип переменной на массив, а бинарный инфиксный оператор [], примененный к объекту типа массива, получит доступ к одному из подобъектов массива.


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

int *p, **pp, i, a[10], &r = i; 

определяет указатель int, указатель на указатель на int, обычный int, массив из 10 int и ссылку int. (Последний сразу же инициализируется, поскольку у вас не может быть неинициализированной ссылки.) Обратите внимание, что модификаторы типа синтаксически принадлежат объявленной переменной, тип которой они изменяют, а не тип объявленной переменной. Тем не менее, модификаторы типа (* и &) изменяют тип переменной.
Однако в следующем случае, когда p, i и a предполагаются уже объявленными переменными

*pp = &i;
a[0] = i;

* и & — это операторы унарного префикса, разыменовывающие pp и дающие адрес i, а [] выдает первый объект int в массиве a.

Тот факт, что C и C++ не заботятся о пробелах вокруг модификаторов типов, и что это привело к разным лагерям, когда дело доходит до их размещения на самом деле не упрощает задачу.
Некоторые люди помещают модификаторы типа рядом с типом. Они утверждают, что он изменяет тип и поэтому должен идти туда:

int* ptr;

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

int* a, b;

определяет a как указатель на int, а b как int. Вот почему некоторые люди предпочитают писать

int *ptr;
int *a, *b;

Я предлагаю просто никогда не объявлять несколько объектов в одном выражении. ИМО, что облегчает чтение кода. Кроме того, это оставляет вам свободу выбора любого соглашения.


Чтобы еще больше усложнить ситуацию, помимо модификаторов типов и унарных префиксных операторов & и * существуют также бинарные инфиксные операторы. & и * означают "побитовое И" и "умножение". И чтобы добавить оскорбление к травме, в С++ вы можете перегружать как унарный префикс, так и бинарный инфикс варианты этих операторов (и бинарный инфикс []) для определяемых пользователем типов и полностью свободны в своей семантике.

person sbi    schedule 28.07.2010
comment
как насчет использования typedef для int* в случае примера строки 2? - person KedarX; 28.07.2010
comment
@Kedar: Действительно, typedef int* intptr; intptr a, b; определяет два int*. Но мой совет остается прежним: одна переменная на объявление/определение. - person sbi; 28.07.2010
comment
Обратите внимание, что вы также можете разыменовывать два раза подряд (или больше), например. int a = 5; int* b = &a; int** c = &b; std::cout << **c;, который получает значение a для **c и печатает 5. - person Andrew; 27.05.2021