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

1.37.2.4. Понятие о недействительном указателе

Недействительный указатель (invalid pointer) – это ненулевой указатель, содержимое которого не является адресом переменной или функции. Любое использование недействительного указателя приводит к неопределенному поведению программы.

1.37.2.5. Определение переменной – указателя

Определение типизированного указателя имеет следующий формат:

тип *имя;

Здесь тип – тип объекта, адрес которого содержит указатель, а имя – имя переменной-указателя. Например,

int* ptr;

Выше определена переменная-указатель ptr, которая может хранить адреса объектов типа int. Отметим, что наличие оператора разыменования (*) делает идентификатор ptr именем указателя. Если в одном определении необходимо объявить два указателя ptr1 и ptr2, то перед именем каждого из указателей следует поставить символ (*). Например,

int *ptr1, *ptr2;

Определение нетипизированного указателя имеет следующий формат:

void *имя;

Например,

void* ptr3;

Переменная ptr3 может хранить адрес элемента любого типа.

Заметим, что определения указателей ptr и ptr3 могут быть переписаны в другой эквивалентной форме:

int* ptr;

void* ptr3;

Такая форма легче читается. Здесь в явном виде представлен тип указателя: int* и void*. Однако такой формой записи следует пользоваться в том случае, когда объявление содержит определение только одной переменной.

Во время определения указатель может быть инициализирован. В качестве инициализаторов указателя при его объявлении могут использоваться:

• Нулевой указатель.

• Указатель-переменная

• Указатель-выражение.

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

int n = 5;

int* p = &n; // Инициализация указателя p значением

// указателя-выражения &n

int* p1 = p; // Инициализация указателя p1 значением

// существующего указателя p

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

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

• Разыменование и взятие адреса,

• Присваивание,

• Арифметические действия с указателями,

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

• Использование указателей в качестве параметров и в качестве возвращаемого значения функции.

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

1.37.2.6.1. Разыменование указателя. Модель переменной-указателя

Оператор разыменования (*) – префиксный унарный оператор. Он используется для доступа к объекту, на который установлен указатель. Для любого типизированного указателя p, образовав выражение *p, получаем доступ к объекту, на который установлен этот указатель. Выражение *p может стоять как слева, так и справа от оператора присваивания.

В качестве примера рассмотрим следующий программный код:

int n = 5; int* p = &n; *p = 10;

После выполнения первых двух строк программного кода будет выделена память для двух инициализированных переменных p и n. В переменную n будет записано число 5, а в переменную p адрес переменной n. Теперь к ячейке памяти, где хранится переменная n, появляется дополнительная возможность обращения с помощью выражения *p. Действительно после выполнения третьей строки кода в переменной n будет храниться новое число (10). Удобно выражение *p рассматривать в качестве синонима переменной n.

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

int* int

p n, *p

указатель объект

1.37.2.6.2. Оператор взятия адреса

Оператор взятия адреса (&) является унарным префиксным оператором. Использование этого оператора приводит к образованию указателя-выражения. В результате выполнения этого выражения возвращается адрес операнда. Оператор взятия адреса уже должен быть знаком студенту по использованию при организации ввода с помощью функции scanf().