Операция new

Операции инкремента и декремента

Операция вычитания

Операция сложения

Операция получения адреса

Операции отношения

Присваивание

p1=p2

где р1 и p2 указатели одного типа.

Пример:

int x=2;

int y=1;

int *p1, *p2;

p1=&x; //p1 указывает на х

p2=p1; //р2 теперь также указывает на х

Операция косвенной адресации (разыменование)

где р указатель.

Эта унарная операция (обозначаемая *) позволяет сослаться на переменную, адрес которой хранится в указателе р, и изменить или использовать значение переменной.

Пример:

int x=5;

int *p1; //объявление указателя

p1=&x; //р1 присваивается адрес х

cout<< *p1<<endl; //5 (обращение к х по адресу)

*p1=10; //изменение переменной х (обращение к х по адресу)

cout<<x; //10

Таким образом, к переменной можно обращаться по ее имени (прямо) и по ее адресу (косвенно).

p1 q p2

где p1 и p2 указатели одного типа, а q знак операции: ==, !=, <, >, <=, >=

Пример:

float x=0.4;

float *p1=&x;

float *p2;

p2=p1;

if (p1==p2) cout<< “equal”

else cout<<“no equal”;

&p

где р указатель.

Пример:

int x=5;

int *p1=&x;

int **p2;

p2=&p1;

cout<<*p1<<’ ‘<<p1<<’ ‘<<*р2<<’ ‘<<**p2<<’ ‘<<p2<<endl;

//5 0063FE00 0063FE00 5 0063FDC

p+k

где p – указатель, k – целое число.

Результатом операции р+k является адрес памяти, расположенной на k единиц дальше от начальных адресов памяти, чем память, адресуемая левым операндом. Длина единицы памяти в операции измеряется длиной базового типа указателя.

Пример:

int a[5]={10,20,30,40,50};

int *p1=&a[1];

p1=р1+3; //р1 увеличивается на 12 байтов

cout<<*p1; //50

char c[6]=”abcdef”;

char *p2=&c[1];

p2=р2+3; //р2 увеличивается на 3 байтa

cout<<*p2; //e

p-k

р1-р2

где p, p1 и p2 – указатели, p1 и p2 одного типа, k – целое число.

Результатом операции р-k является адрес памяти, расположенной на k единиц ближе к начальным адресам памяти, чем память, адресуемая левым операндом.

Пример:

int a[5]={10,20,30,40,50};

int *p1=&a[1];

p1=р1-1;

cout<<*p1; //10

Результатом операции р1-р2 является количество единиц памяти, между двумя адресами. Длина единицы памяти измеряется в операции длиной базового типа указателей.

Пример:

int a[5]={10,20,30,40,50};

int *p1=&a[1];

int *p2=&a[3];

cout<<p2-p1; //2

p++ и p- -

где p указатель.

Операции изменяют значение указателя на единицу памяти (равную емкости базового типа).

Пример:

int a[5]={10,20,30,40,50};

int *p1=&a[1];

int *p2=&a[3];

p1++;

p2--;

cout<<*p1<<’ ‘<<*p2; //30 30

В рассмотренных примерах указатели указывали на обычные переменные. Указатели в программах чаще используют для хранения адресов динамических переменных. Динамические переменные, в отличие от обычных переменных, не объявляются, а память под них выделяется во время работы программы. Для создания динамической переменной используется операция new.

Операция new может использоваться следующими способами:

new тип

new тип (начальное значение)

new тип [количество элементов]

В первом способе операция выделяет участок динамической памяти, размер которого определяется емкостью указанного для операции типа. Во втором способе выделенная память инициализируется начальным значением. В третьем способе операция выделяет память под указанное количество элементов. Результатом операции является адрес выделенной памяти.

Примеры:

int *p;

p=new int; //выделение памяти под данное целого типа

*p=5;

int *p1;

p1=new int [10]; //выделение памяти под массив из 10 чисел

//Заполнение выделенной памяти

*p1=10;

*(p1+1)=20;

for (int i=2;i<10; i++)

*(p1+i)=(i-1)*10;

float p2;

p2=new float(0.5); //инициализация выделенной памяти

Память для динамических переменных выделяется из области памяти, которая называется динамической памятью или кучей (heap). Хотя эта область большая, но и она может исчерпаться. Поэтому программист должен заботиться о своевременном освобождении памяти, если необходимость в ней исчезает.

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

Программист должен заботиться о своевременном освобождении динамической памяти, если необходимость в ней исчезает.