Указатели и массивы
Понятие ссылки
Ссылки
Операции с указателями
С указателями можно выполнять следующие операции:
1) разыменование (*);
2) присваивание;
3) арифметические операции (сложение с константой, вычитание,
инкремент ++, декремент --);
4) сравнение;
5) приведение типов.
1) Операция разыменования предназначена для получения значения переменной или константы, адрес которой хранится в указателе. Если указатель указывает на переменную, то это значение можно изменять, также используя операцию разыменования.
Примеры:
int a; //переменная типа int
int*pa=new int; //указатель и выделение памяти под динамическую переменную
*pa=10;//присвоили значение динамической переменной, на которую указывает указатель
a=*pa;//присвоили значение переменной а
Присваивать значение указателям-константам запрещено.
2) Приведение типов
На одну и ту же область памяти могут ссылаться указатели разного типа. Если применить к ним операцию разыменования, то получатся разные результаты.
int a=123;
int*pi=&a;
char*pc=(char*)&a;
float *pf=(float*)&a;
printf("\n%x\t%i",pi,*pi);
printf("\n%x\t%c",pc,*pc);
printf("\n%x\t%f",pf,*pf);
При выполнении этой программы получатся следующие результаты:
66fd9c 123
66fd9c {
66fd9c 0.000000
Т. е. адрес у трех указателей один и тот же, но при разыменовании получаются разные значения в зависимости от типа указателя.
В примере при инициализации указателя была использована операция приведения типов. При использовании в выражении указателей разных типов, явное преобразование требуется для всех типов, кроме void*. Указатель может неявно преобразовываться в значения типа bool, при этом ненулевой указатель преобразуется в true, а нулевой в false.
3) Арифметические операции применимы только к указателям одного типа.
- Инкремент увеличивает значение указателя на величину sizeof(тип).
Например:
char *pc;
int *pi;
float *pf;
. . . . .
pc++;//значение увеличится на 1
pi++;//значение увеличится на 4
pf++;//значение увеличится на 4
- Декремент уменьшает значение указателя на величину sizeof(тип).
- Разность двух указателей – это разность их значений, деленная на размер типа в байтах.
Например:
int a=123,b=456,c=789;
int*pi1=&a;
int *pi2=&b;
int*pi3=&c;
printf("\n%x",pi1-pi2);
printf("\n%x",pi1-pi3);
Результат
Суммирование двух указателей не допускается.
Можно суммировать указатель и константу:
pi3=pi3+2;
pi2=pi2+1;
printf("\n%x\t%d",pi1,*pi1);
printf("\n%x\t%d",pi2,*pi2);
printf("\n%x\t%d",pi3,*pi3);
Результат выполнения программы:
66fd9c 123
66fd9c 123
66fd9c 123
При записи выражений с указателями требуется обращать внимание на приоритеты операций.
Ссылка – это синоним имени объекта, указанного при инициализации ссылки.
Формат объявления ссылки
тип & имя =имя_объекта;
Примеры:
int x;// определение переменной
int& sx=x;// определение ссылки на переменную х
const char& CR=’\n’;//определение ссылки на константу
8.1. Правила работы со ссылками:
1) Переменная ссылка должна явно инициализироваться при ее описании, если она не является параметром функции, не описана как extern или не ссылается на поле класса.
2) После инициализации ссылке не может быть присвоено другое значение.
3) Не существует указателей на ссылки, массивов ссылок и ссылок на ссылки.
4) Операция над ссылкой приводит к изменению величины на которую она ссылается
Ссылка не занимает дополнительного пространства в памяти, она является просто другим именем объекта.
Пример1:
#include <iostream.h>
void main()
{
int I=123;
int &si=I;
cout<<”\ni=”<<I<<” si=”<<si;
I=456;
cout<<”\ni=”<<I<<” si=”<<si;
I=0; cout<<”\ni=”<<I<<” si=”<<si;
}
Выведется
I=123 si=123
I=456 si=456
I=0 si=0