Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
учебное пособие ОАиП.doc
Скачиваний:
11
Добавлен:
25.04.2019
Размер:
2.63 Mб
Скачать

Указатели Понятие указателя

В языках высокого уровня обычно нет необходимости знать адреса памяти, где расположены данные и оперирующие ими переменные. В С(С++) предусмотрен удобный механизм получения адресов данных. И соответственно, если имеется адрес, то несложно получить (или разместить) значение по этому адресу.

Указатель - это переменная (группа ячеек), содержащая адрес некоторой переменной или группы переменных(массив). Если переменная объявлена как указатель, то она содержит адрес памяти, по которому может находится скалярная величина любого типа. При объявлении переменной типа указатель, необходимо определить тип объекта данных, адрес которых будет содержать переменная, и имя указателя с предшествующей звездочкой (или группой звездочек). Формат объявления указателя:

[ модификатор ] спецификатор_типа * идентификатор.

Память ЭВМ можно представить в виде массива последовательно пронумерованных и проадрессованных ячеек, содержимым которых можно опе­рировать по отдельности или связными группами. Унарная операция & выдает адрес объекта, таким образом, инструкция p=&k; присваивает адрес первого байта перемен­ной k в переменную p. В этом случае говорят, что p указывает на k. Различие между ними состоит в том, что p - это переменная, а &k - константа. Операция & применяется только к объектам, непосредственно расположенным в памяти (переменные, элементы массива, структуры). Ее операндом не может быть ни выражение, ни константа, ни регистровая переменная.

Если мы имеем переменную p, являющуюся ссылкой (адресом), то для доступа к значению по этому адресу можно воспользоваться операцией косвенной адресации (*). Выражение kk=*p - позволяет переменной kk передать значение, на которое указывает p (расположенное по адресу p).

Как уже отмечалось, для того чтобы иметь возможность оперировать с некоторым объектом, он должен быть описан как объект определенного типа. Аналогично и с указателями на эти объекты.

Описание указателей

Из рассмотренного ранее материала следует, как описать переменную любого из известных типов. Как описать переменную типа "указатель"? Для этого необходимо указать, на переменную какого типа воз­можна ссылка через объявляемый указатель. Это связано с тем, что для выпол­нения некоторых адресных операций необходимо знать размеры памяти, отводи­мой под объекты, на которые указывает указатель. Ниже приводятся примеры описания указателей:

int *p; // p - указатель на элементы типа int

float *k,*k1; // k и k1 – два указателя на элементы типа float

char *s; // s – указатель на элементы символьного типа

Адрес - это целое число без знака, поэтому при выводе на печать значения указателя (p,k,k1,s) будем использовать формат %u. Исключением является безтиповый указатель, то есть указатель вида:

void *pp;

Указатель типа void* указывает на место в оперативной памяти, но не содержит информации о типе объекта и может быть использована для адресации данных любого типа. Однако для выполнения арифметические и логические операции над этими указателями или объектами, на которые они указывают, необходимо при выполнении каждой операции явно определить тип объекта. Это может быть выполнено с помощью операции приведения типов. Иначе компилятору неизвестно, какой длины поле памяти должно использоваться в операции.

Для правильной работы указатель должен ссылаться на объекты только соответствующего ему типа. При этом компилятором не контролируется нарушение этого требования. Рассмотрим эту ситуацию на примере перезаписи значения переменной a в переменную b.

#include <stdio.h>

void main(void)

{ int *p;

float a=10.25,b;

p= &a;

b= *p;

printf(“a= %f b= %f”,a,b);

}

Значение переменной a не будет перенесено в переменную b, так как p является целочисленным указателем. И так как р адресует двухбайтную ячейку памяти, то в переменную b будут переписаны только 2, а не 4 байта из переменной a.