Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции_по_пяву_4.doc
Скачиваний:
101
Добавлен:
15.03.2015
Размер:
1.29 Mб
Скачать
    1. Операции с указателями

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

  • Разыменование,

  • Взятие адреса,

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

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

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

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

      1. Дополнительные сведения о разыменовании указателей

Как отмечалось выше, разыменование – операция позволяющая получить доступ к объекту, на который установлен указатель. Однако эта операция допустима не ко всем указателям. Остановимся на тех категориях указателей, к которым нельзя применять разыменование:

  • Недействительный указатель.

  • Нетипизированный указатель.

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

Приведем примеры недопустимых разыменований.

/* Примеры недопустимых разыменований указателей */ int* p = NULL;

*p = 10; /* Недопустимо разыменовывать нулевой указатель*/ int n = 5; void* p3 = &n; *p3 = 10; /* Недопустимо разыменовывать нетипизированный указатель p3*/ char* p4;

*p4 = ’A’; /* Недопустимо разыменовывать неинициализированный указатель p4 */ /* . . . . . . . . . . . . . . . . . . . . . . . . . . . */

Заметим, что к категории операторов разыменования относятся еще два оператора:

  • Оператор [], который используется при работе с массивами.

  • Оператор ->, который используется при работе со структурами.

      1. Присваивание указателей

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

/* Корректные и некорректные присваивания типизированных указателей */ int n = 10; double x = 20.3; int *p1, p2; double* p3;

p1 = &n; /* допустимое присваивание */ p2 = p1; /* допустимое присваивание */ p3 = p2; /* недопустимое присваивание, т. к. не совпадают базовые типы указателей */ /* конец программного кода примера */

Отметим, что, несмотря на семантическую недопустимость присваивания p3 =p1 в приведенном выше примере компилятор языка Си ограничивается выводом предупреждения (Компилятор языка С++ в этой ситуации выводит сообщение об ошибке). Работа языка Си с указателями свидетельствует о его пониженной типизации. Это обстоятельство следует рассматривать как крайне опасным последствиям. Одна из рекомендаций по преодолению этих неприятностей заключается в предварительной компиляции программного кода компилятором языка С++.

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

/* Корректные и некорректные присваивания типизированных указателей */ int n = 10; double x = 20.3; int *p1, p2; double* p3;

p1 = &n; /* допустимое присваивание */ p2 = p1; /* допустимое присваивание */ p3 = p2; /* недопустимое присваивание, т. к. не совпадают базовые типы указателей */ /* конец программного кода примера */

Отметим, что, несмотря на недопустимость присваивания p3 =p1 в приведенном выше примере компилятор языка Си ограничивается выводом предупреждения (Компилятор языка С++ в этой ситуации выводит сообщение об ошибке).