Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ГЛАВА 7 Указатели.doc
Скачиваний:
25
Добавлен:
29.02.2016
Размер:
143.36 Кб
Скачать

Инициализация указателей

Как и другие переменные, помимо объявления, указатели требуют инициализации, так как в противном случае они содержат непредсказуемые значения. Существуют следующие способы инициализации указателя:

  • присваивание указателю адреса существующего объекта (переменной, массива и др.) с помощью операции адреса (&):

int a = 5;

int * p = &a; или int * p(&a);

  • присваивание указателю пустого значения:

int *p = NULL; или int * p = 0

  • с помощью значения другого инициализирующего указателя:

int * p1 = p; или int * p1(p);

  • c помощью имени массива:

int b[10]; int *p = b; (cм. главу 8)

  • присваивание адреса динамической памяти:

int *p = new int; (cм. главу 9)

Адресная арифметика

Под адресной арифметикой (или арифметикой над указателями) понимаются действия над указателями, связанные с использованием адресов памяти. Рассмотрим основные операции, которые можно применять к указателям, а какие – нельзя.

  1. Операция адреса

Так как указатель – это переменная, то для получения адреса памяти, где расположен указатель, можно использовать операцию адреса (&):

int * p, x = 5; p = &x;

cout<<&x<<&p<<endl;

  1. Операция присваивания

Указателю можно присвоить адрес переменной

p = &x, где p – указатель, x – имя переменной.

Указатели можно присваивать один другому, если оба указателя одного типа:

int x = 5; int * p = &x;

int * q = p;

cout<<*p<<' '<<*q<<endl; // 5 5

  1. Операция разыменования

Определение значения, на которое ссылается указатель p:

int * p, n, m = 5;

p = &m; // p присвоен адрес переменной m

n = * p; // переменная n примет значение 5

*p = -13; // переменная m примет значение -13

  1. Увеличение/уменьшение указателя

Основными арифметическими операциями, применимыми к указателям, являются операции увеличения и уменьшения указателя:

имя_указателя + i и имя_указателя – i, где

имя_указателя – переменная типа указатель; i значение типа int.

Результатом операции имя_указателя + i является указатель на i-й элемент после элемента, адрес которого находится в данном указателе, а имя_указателя - i – указатель на i-й элемент до элемента, адрес которого находится в данном указателе.

double d,*p; int n;

p = &d;

n = 3; p = p + n; // в p адрес увеличился на 24

p =n + p; // в p адрес увеличился ещё на 24

Если к указателю применяется операция инкремента (++) или операция декремента (--), то значение указателя увеличивается или уменьшается на размер данных, которые он адресует.

long b;

long * p; // p – указатель на тип long

p = &b; // в p адрес переменной b

p++; // в p адрес увеличится на 4

p--; // в p адрес уменьшится на 4

  1. Вычитание указателей

При работе с указателями можно использовать операцию вычитания двух указателей:

имя_указателя1 – имя_указателя2

Операция имеет смысл, только если обе переменные являются указателями на один и тот же набор данных (например, массив). Результатом операции является целое число, которое показывает сколько элементов соответствующего типа можно расположить между адресами памяти, на которые указывают указатели имя_указателя1, имя_указателя2.

  1. Операции сравнения

Указатели на данные одного и того же типа можно сравнивать с помощью обычных операций сравнения: ==, !=, >, >=, <, <=.

При сравнении указателей сравниваются их значения (хранимые в них адреса), а не значения величин, на которые данные указатели указывают. Результатом операций сравнения является целое число (0 или 1).

Сравнение указателей с числовыми значениями как сравнение данных разных типов не определено.

  1. Операция sizeof

Для определения, сколько байтов отводится под указатель, можно использовать операцию sizeof(указатель). Количество байтов зависит от модели памяти (обычно 4 байта).

  1. Недопустимые операции

К указателям можно применять только описанные операции и операции, которые выражаются через них, например, разрешается к указателю применить операцию uk += n; , так как ее можно выразить через uk = uk+n; . Следующие операции недопустимы с указателями:

  • сложение двух указателей;

  • вычитание двух указателей на данные различных типов;

  • сложение/вычитание указателей с числом с плавающей точкой;

  • умножение/деление указателей;

  • поразрядные операции и операции сдвига.

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

*p++ = 10;

Операции разыменования и инкремента имеют одинаковый приоритет и выполняются справа налево, но поскольку инкремент постфиксный, он выполняется после операции приcваивания. Таким образом, сначала по адресу, записанному в указателе p, будет записано значение 10, а затем указатель будет увеличен на количество байтов, соответствующее его типу.

Оператор (*p)++ напротив, увеличивает на единицу значение, на которое ссылается указатель p.