Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лабораторная работа №9(2).doc
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
817.66 Кб
Скачать

Указатели на указатели

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

тип **имя_указателя_на_указатель;

При объявлении указателя на указатели уровнем вложенности указателей служит число звездочек перед именем переменной.

Для получения значения по указателю на указатели перед именем указателя надо записать количество звездочек, равное уровню вложенности указателя.

Например:

int iV, jV;

int* pV=&iV; // pV - это адрес,

//а *pV - значение

int** ppV=&pV;

int*** pppV=&ppV;

iV=77; // Эквивалентно **ppV=77;

jV=*pV; // Эквивалентно jV=**ppV;

// или jV=***pppV;

Бестиповый (нетипизированный) указатель

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

void* ptr;

Для указателя на тип void не определена операция обращения по адресу *, не определена адресная арифметика. Использование безтиповых указателей ограничено работой с памятью при использовании ряда системных функций, передачей адресов в функции, написанные на языках программирования более низкого уровня, например на ассемблере.

В программе на языке С безтиповый указатель может применяться там, где адрес интерпретируется по-разному, в зависимости от каких-либо динамически вычисляемых условий. Например, приведенный ниже фрагмен будет печатать целое число, содержащееся в одном, двух или четырех байтах, расположенных по передаваемому адресу:

if (nbytes == 1) {

char* cptr = (char*)ptr;

printf( "%c",*cptr);

} else if (nbytes == 2) {

short* sptr = (short*)ptr;

printf( "%d",*sptr);

} else if (nbytes == 4) {

long* lptr = (long*)ptr;

printf( "%d",*lptr);

} else {

Printf("Неверное значение аргумента");

}

}

В примере используется операция явного преобразования типа. Имя типа, заключенное в круглые скобки, стоящее перед выражением, преобразует значение этого выражения к указанному типу. Разумеется, эта операция может применяться к любым указателям.

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

В программах на языке С значение указателя, равное нулю, используется в качестве "неопределенного" значения. Например, если какая-то функция вычисляет значение указателя, то чаще всего нулевое значение возвращается в случае ошибки.

long* foo(void);

. . .

long* resPtr;

if ((resPtr = foo()) != 0) {

// использовать результат

} else {

// ошибка

}

В языке С определена символическая константа   NULL для обозначения нулевого значения указателя.

Такое использование нулевого указателя было основано на том, что по адресу 0 данные программы располагаться не могут, он зарезервирован операционной системой для своих нужд. Однако во многом нулевой указатель – просто удобное соглашение, которого все придерживаются.

Преобразование типа указателя

Указатель типа void может быть преобразован к указателю любого другого типа только явным приведением типа. Но указатель любого типа может быть неявно преобразован к указателю типа void.