Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ГЛАВА 7 Указатели.doc
Скачиваний:
25
Добавлен:
29.02.2016
Размер:
143.36 Кб
Скачать

Указатель в качестве возвращаемого значения функции

Функции могут не только принимать указатели в качестве аргументов, но и возвращать их.

Чтобы вернуть указатель, функция должна объявить его тип в качестве типа возвращаемого значения. Например, int* fun(); – объявление функции, которая должна вернуть указатель на целое число.

Если функция возвращает указатель, то значение, используемое в её операторе return, также должно быть указателем (как и для всех функций, return-значение должно быть совместимым с типом возвращаемого значения).

// Пример 7.3. Функция возвращает указатель.

// Передача аргументов в функцию по указателю.

#include<iostream>

using namespace std;

int* fun(int*, int*);

int main(){

int a = 2, b = 7, * p;

p = fun(&a, &b);

cout<<*p<<endl;

system("pause");

}

int* fun(int* x, int* y){

if(*x > *y)return x; else return y;

}

// Пример 7.5. Функция возвращает указатель.

// Передача аргументов в функцию по значению.

#include<iostream>

using namespace std;

int* fun(int, int);

int main(){

int a = 2, b = 1, *p;

p = fun(a, b); cout<<*p<<endl;

system("pause");

}

int* fun(int x, int y){

int * t;

if(x > y) t = &x; else t = &y;

return t;

}

Некоторые особенности использования указателей Нулевые указатели

Нулевой указатель – это указатель, который в данный момент не адресует никакого достоверного значения в памяти. Значение нулевого указателя равно нулю – единственный адрес, к которому нет доступа.

Указателю можно присвоить нулевой адрес следующим оператором:

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");

}

11