Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Методичка_Программирование_1.doc
Скачиваний:
8
Добавлен:
19.11.2019
Размер:
501.25 Кб
Скачать

6.2.Операции с указателями

Основные операции над указателями это присваивание и разыменование.

Операция присваивания записывает в указатель адрес какого-то объекта в памяти. Для того, чтобы узнать адрес какого-либо объекта, используется оператор взятия адреса – «&». Например, чтобы присвоить указателю p адрес переменной a нужно записать:

p = &a.

Обратная операция называется операцией разыменования. Результатом этой операции является переменная, которая хранилась по адресу, на который ссылался указатель. Эта операция указывается с помощью оператора «*». Например, следующий код запишет в переменную a число 1:

p = &a;

*p = 1;

А следующее выражение увеличит значение переменной a на 1:

(*p)++;

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

Над указателями можно выполнять и арифметические действия сложения и вычитания (а также инкремента и декремента). Рассмотрим следующий фрагмент кода:

int a[]={0,1,2,3,4};

int b;

int* p = &a[2];

p++;

b=*p;

Чему будет равно значение b после его выполнения?

В третьей строке в указатель p был записан адрес элемента a[2].

В четвертой строке этот адрес должен быть увеличен на 1. В С при прибавлении к указателю 1 он увеличивается таким образом, чтобы указывать на следующий в памяти элемент соответствующего типа. Например, если переменная целого типа занимает 4 байта, то адрес, хранящийся в указателе, увеличивается на 4. В пример, после увеличения на 1 указатель будет указывать на следующий элемент массива, т.е. на a[3].

В результате операции в последней строке в b будет записано число 3.

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

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

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

6.3.Указатели и массивы

Операция индексирования, по сути, также является операцией адресной арифметики. Можно записать следующее равенство: a[i]=a+i. Фактически, имя массива a является указателем на начало массива. Однако, в отличие от обычных указателей, адрес массива определяется во время компиляции и не изменяется во время выполнения программы.

Сравним два объявления:

int a[10];

int *p;

В первом случае компилятор отведет в памяти место под 10 переменных целого типа и запомнит адрес нулевого элемента. Этот адрес он будет подставлять как константу во все выражения, где встретиться переменная a.

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

За исключением сказанного, указатель и массив схожи. Можно в указатель переписать указатель на массив: p=a. Обратите внимание, операция взятия адреса тут не требуется. Над массивом можно выполнять адресные операции (которые не изменяют указатель на массив), а над указателем можно выполнять операцию индексирования.