Некоторые особенности использования указателей
Нулевые указатели
Нулевой указатель – это указатель, который в данный момент не адресует никакого достоверного значения в памяти. Значение нулевого указателя равно нулю – единственный адрес, к которому нет доступа.
Указателю можно присвоить нулевой адрес следующим оператором:
int *p = 0;
Существует стандартная описанная во многих заголовочных файлах константа NULL, обозначающая нулевой адрес. Таким образом, предыдущему оператору равносилен следующий оператор:
int *p = NULL;
Присваивание нулевого значения указателю является инициализацией и может защитить программу от ошибок, вызванных использованием неинициализированных указателей.
Как и другие глобальные переменные, глобальные указатели инициализируются значениями, равными нулю, во всех остальных случаях требуется явная инициализация, например, int *p = &c;
Часто при программировании используются проверки вида
if(p != NULL) оператор; // выполняется оператор, если
// p адресует достоверные данные
if(!p) оператор; // равнозначная запись
Указатели на тип void
В языке С++ можно встретить также указатели типа void, которые указывают на неопределённый тип данных:
void * vp;
Указателю на void можно присвоить адрес данного любого типа, но указатель на void нельзя разыменовать, пока он не приведён к какому-либо конкретному типу, так как неизвестно, на какой объём памяти он указывает:
void *p; double f = 12.34;
p = &f; cout<<*(double*)p<<endl; // 12.34
Не следует путать нулевой указатель и указатель на тип void. Нулевой указатель не адресует достоверных данных, а указатель на voidадресует данные неопределённого типа и также может быть нулевым.
Указатель на void нельзя разыменовать, пока он не приведён к конкретному типу
Указатели на константу и константные указатели
При объявлении указателей, как и обычных переменных, может использоваться спецификатор const. Например, в следующих операторах
int x = 15, k = 10; const int * p = &x;
наличие спецификатора constозначает, что указатель содержит адрес константы, следовательно, значение, находящееся по данному адресу, меняться не может, т.е. при выполнении оператора *p = 7;
компилятором будет выдано сообщение об ошибке. Но в этом случае возможно выполнение оператора p = &k;
Если же спецификатор const стоит между символом * и именем указателя, то сам указатель является константой:
int x = 15, k=10; int* const p = &x;
При этом можно выполнить оператор *p = 7;, но p = &k; – нельзя (компилятором будет выдано сообщение об ошибке).
Если же в объявлении будет два спецификатора const, как например, в следующих операторах
int x = 15, k = 10; const int* const p = &x;
то нельзя будет изменить ни сам указатель, ни значение, находящееся по адресу в нем.
// Пример 7.4. Использование сonst-указателя и указателя на сonst.
#include<iostream>
using namespace std;
int main(){
int x = 333; int y = 777;
// const_указатели
// должны быть проиницилизированы сразу при объявлении!
int * const px = &x;
*px = 999; // можно
// px = &y; // !!!! нельзя
const int *py; py = &y; // укзатель на сonst
py = &x; // можно
// *py = 111; !!!! нельзя
*(int*)py = 555; // можно! Приведение типа к (int*) необходимо,
// чтобы избавиться от указателя на константу
system("pause");
}
Дата добавления: 2022-05-27; просмотров: 75;