
Int main()
{
double a=1.;
double *ptr_a = &a;
cout<<a<<' '<<sizeof(a)<<' '<<ptr_a<<' '<<sizeof(ptr_a)<<' '<<*ptr_a<<endl;
return 0;
}
Переменные–указатели pc и ptr имеют разные права – к ptr нельзя обратиться как *ptr, он не связан ни с каким участком памяти, но после ptr=&cc уже можно - *cc и *ptr – синонимы имени cc.
Ошибочная запись - *p=’-‘; - Пытаемся что-то положить в неопределенный участок памяти.
Чтобы связать неинициализированный указатель с новым участком памяти, еще не занятым никаким объектом пишут
p = new char; или присвоить явный адрес
p = (char *)0xb80000000; при этом не забыть привести адрес к типу p.
После чего уже можно писать операторы вида cin>> *p;
Операцию ‘*’ разыменования указателя в выражении можно объяснить как – получение значения, размещенного по адресу, равному значению указателя. А ту же операцию, но в левой части оператора присваивания, как – разместить значение по адресу, равному значению указателя.
При определении указателя сам указатель и его значение могут быть объявлены константами.
type [const] * [const] имя_указателя [инициализатор];
Причем ближайший к имени указателя модификатор const относится к нему, а – ближайший к типу определяет постоянность начального значения, связанного с указателем.
Например, type const * имя_указателя [инициализатор]; - формат определения указателя на константу.
const int zero = 0;
int const *point_to_const = &zero;
//недопустимы операторы вида
*point_to_const = 1;
cin>>*point_to_const;
//допустимы
point_to_const = &cc;
point_to_const = NULL;
Ограничения использования операции взятия адреса - &
-
Применима к объектам, имеющим имя и размещенным в памяти
-
Нельзя применять к регистровым переменным, битовым полям структур и объединений, к внешним объектам (файлам)
Например,
&(23*f-6)
&2.71828
int register numb = 1;
int *ptr_numb = &numb;
const float Euler = 2.718282;
float *pEuler = (float *)&Euler;
Более подробно о ссылках
Итак, ссылка – особый тип данных, являющийся скрытой формой указателя, который при использовании автоматически разыменовывается. При объявлении должна быть тут же проинициализирована именем того объекта, на который ссылается
type &name_ref = name_var;
Пример
char Letter_A = ‘A’;
char &ref = Letter_A;
Ссылка – псевдоним, любое изменение значения ссылки влечет изменение объекта, на который ссылка указывает
int i=0;
int &ref = i;
ref +=10; // ~ i +=10;
или
char Letter_A = ‘A’;
char &ref = Letter_A;
char Letter_B = ‘B’;
char &ref = Letter_B; // Тогда Letter_A = Letter_B
Действие со ссылкой сказывается на самом объекте. Ссылаться на тип объекта нельзя. Ссылки не могут указывать на нулевой объект (принимающий значение NULL), тогда надо использовать указатель. Использование ссылок не связано с дополнительными затратами памяти.
Пример сравнения ссылок с указателями в качестве фактических параметров
void swap(double *a, double *b)
{
double c = *a;
*a = *b;
*b = c;
}
void swap(double &a, double &b)
{
double c = a;
a = b;
b = c;
}
void main()
{
double c = 1.21;
double d = 43.1;
swap(&c, &d);
cout<<”c=”<<c<<”\t\td=”<<d<<endl;
swap(c,d);
cout<<”c=”<<c<<”\t\td=”<<d<<endl;
}
int n = -22;
void invert(int& k=n)
{
cout<<”k=”<<k<<endl;
k = -k;
}
void main()
{
int a = 21;
int b = 34l;
invert();
cout<<”n=”<<n<<endl;
invert(a);
cout<<”a=”<<a<<endl;
invert(a+b);
cout<<”a=”<<a<<”b=”<<b<<endl;
double r = 2.212;
invert(int(r));
cout<<”r=”<<r<<endl;
}