Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
лекции по титп.doc
Скачиваний:
9
Добавлен:
24.09.2019
Размер:
249.86 Кб
Скачать

Арифметика указателей

С указателями можно производить следующие арифметические операции:

  1. Увеличение указателя на целое число

Пример:

int n;

int * pn=&n;

pn2=pn; //присваиваем значение указателя pn указателю pn2

pn++; // увеличение указателя на единицу означает увеличение его на величину элемента типа sizeof (pn)

pn2=pn+5;

  1. Сравнение

if ( pn2==pn) //сравнивать можно только в том случае, если оба указателя указывают на однотипные объекты и последовательно располагаются в памяти

bool bBigger = (pn2>pn);

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

  1. Разность двух указателей

int number=pn2-pn; // насколько элементов данного типа один адрес отстаёт от другого

аПрямая соединительная линия 28 дрес pn2-адрес pn

sizeof(int)

Сложение двух указателей бессмысленно, поэтому запрещено.

Указатель типа void*

int *a;

void *a;

Так как указатель - это адрес, то его значение не зависит от того, на какой тип объекта он указывает. Значение типа объекта становится необходимым только тогда, когда компилятор оперирует содержимым. Существует специальный вид указателя на объекты С++ любого типа. Ключевое слово void говорит об отсутствии данных о размере указателя в памяти.

Указатель типа void может содержать объекты любого типа.

Пример:

void * pVoid;

int a=2, n=1;

char c;

int *pn=&a;

pVoid=&n;

pVoid=&c;

pVoid=pn;

В данном примере указатель pVoid указывает на различные типы данных (int, char и указатель).

// pn=pVoid; // error

Для корректной манипуляции указателями типа void необходимо явно указывать компилятору, каков тип объекта, на который указывает указатель типа void.

pn=(int*) pVoid; //Можно

pn=static_cast<int*>(pVoid);// можно, явное приведение типов

int m=*pVoid; // так нельзя получать значение той переменной, на которую указывает void, т.к. не знаем какой тип будет в Void * pVoid

int a=5;

int *pa=&a; // присваиваем указателю адрес переменной а

int b=*pa; // разыменовывание указателя, получаем значение переменной, на которую указывает b

size_t c=sizeof(pVoid); // c=4 (размер адреса)

NULL – pointer

В С++ существует специальное значение указателя – нулевое, определяется как (void*)0. Такое значение используется как признак некорректности указателя.

int *p=0;

Assert (p!=0) // проверка на это условие позволяет программе продолжить работу, если не выполнено, то abort

p++;

Указатель на указатель

Сам указатель, как и любая переменная, тоже имеет адрес, значение которого можно получить аналогично получению адреса любой переменной.

T object;

T*p=&object;

T**pp=&p;

Указатель и ключевые слова const, volatile

Ключевые слова const, volatile могут быть использованы при объявлении указателя. Ключевые слова могут относиться к адресу или к объекту (или к тому и другому одновременно).

  1. Указанное значение является константой

const char*pc; = char const *pc;

pc= “ABC”

char c=*pc;

pc++;

// *pc= ‘w’;

Замечания:

  1. char *p=pc; // ошибка, разные типы

  2. volatile char *p; // указанное значение может быть изменено извне

  1. указатель является const (адрес менять нельзя)

char c= ‘A’;

char *const pc=&c;

*pc=B; //OK

// pc++; // ERROR

Указатель является константой, т.е. попытка изменить сам указатель вызовет ошибку компилятора, но ничто не мешает изменить значение (инициализация обязательна).

  1. указатель и указываемое значение является константой

int x=1, nN2=8;

const int *const pn=&x;

// int const * const pn=&x; //только посмотреть объект

int y=*pn; // OK

// *pn=5; // ERROR

// pn=&nN2; // ERROR

  1. указатель на переменную, объявленную ключевым словом const, должен быть также объявлен, как указатель на const

Пример:

const int nN=1;

nN++; // ERROR

const int nN [3]={1,2,3};

i

nN

nt a;

1

2

3

c out<< *(&nN);

cout<< *((&nN)++);// так нельзя

const int a=*(&nN[1]); //нельзя

cout<<a;

cout<< *(&nN++);

Пример:

const int nN=1;

const int*pn1=&nN;

// int * pn2=&nN; //ошибка, иначе была бы возможность модифицировать константное значение nN

(*pn2)++;

В случае, если нам требуется снять константность указателя , необходимо пользоваться оператором const_cast.