Добавил:
СПбГУТ * ИКСС * Программная инженерия Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Язык Си. Лабораторные работы / Справочник. Часть 2 (СПбГУТ).doc
Скачиваний:
47
Добавлен:
10.09.2019
Размер:
801.79 Кб
Скачать

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

Если имеются два указателя (p1 и p2), установленные на элементы одного и того же массива, то можно вычислить их разность (p1 – p2). Результат выполнения этой операции имеет тип int. Возвращаемое значение при этом равно количеству элементов массива, расположенных между элементами, на которые установлены эти указатели. Рассмотрим пример.

int ar[6] = {1, 3, 5, 7, 9, 11}; int* p1 = ar; int* p2 = &ar[3]; int* p3 = &ar[5]; printf(“p1 – p2 = %d\n”, p1 – p2); printf(“p3 – p2 = %d\n”, p3 – p2);

Вывод результата на экран дисплея.

p1 – p2 = -3 p3 – p2 = 2

1.37.2.6.7. Индексирование указателей

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

int ar[6] = {1, 3, 5, 7, 9, 11}; int* par = ar; int n = 4; int* pn = &n; for(int i = 0; i < 6; i++) { printf("%d\n", ar[i]); printf("%d\n", par[i]); printf("%d\n", pn[i]); // Семантическая ошибка. Операция // индексирования применена к // указателю, установленному на // одиночный объект }

Отметим, что при компиляции рассматриваемого кода в системе программирования Code:: Blocks 13.12 не было выдано ни сообщений об ошибках, ни предупреждений.

Заметим, что индексирование в языке является одной из форм разыменования и может быть заменено совокупностью арифметических операций и основной формы разыменования с помощью оператора *. Например, вместо выражения ar[i] в приведенном выше программном коде можно написать *(ar + i).

1.37.2.6.8. Сравнение указателей

Указатели, установленные на элементы одного и того же массива, можно сравнивать с помощью операторов на равенство и операторов отношений. При сравнении указателей сравниваются адреса в памяти. Чаще всего используется оператор сравнения на равенство, чтобы определить, не содержит ли указатель значение NULL.

1.37.2.7. Указатели и динамическая память

Указатели часто используются при работе с динамической памятью. Применение динамической памяти повышает эффективность использова­ния оперативной памяти компьютера. При этом возрастают трудности про­граммирования. Это связано с тем, что программист должен самостоятельно следить за выде­лением и освобождением памяти.

В языке Си имеются четыре функции, предназначенные для работы с динамической памятью: malloc, calloc, realloc и free. Первые три функции служат для выделения динамической памяти. По­следняя функция предназначена для освобождения памяти.

Функция malloc

#include<stdlib.h> void* malloc(size_t size);

Эта функция делает попытку выделить непрерывный блок памяти размером size байт. В случае успеха функция возвращает указатель на начало выделенной памяти. В случае неуспеха функция вернет указатель NULL. После завершения работы с выделенной памятью ее следует освободить вызовом функции free().

Функция calloc

Объявление этой функции имеет следующий вид

#include<stdlib.h> void* calloc(size_t nmemb, size_t size);

Делает попытку выделить непрерывный блок памяти для nmemb объектов размером size байт каждый. В случае успеха функция возвращает указатель на начало выделенной памяти. В случае неуспеха возвращается указатель NULL. Выделенная память заполняется двоичными нулями. После завершения работы с выделенной памятью ее следует освободить вызовом функции free().