Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ПЯВУ - С-С++методичка и титул.doc
Скачиваний:
12
Добавлен:
08.11.2019
Размер:
789.5 Кб
Скачать

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

Выше было показано, что имя массива указателей является указателем-константой на первый элемент массива. Так как первый элемент массива сам является указателем, то имя массива указателей является указателем на указатель (константой). В языке С можно описать и переменную типа “указатель на указатель”. Признаком такого типа является повторение символа ‘*’ при описании переменной. Число звездочек * определяет число “уровней” указателя. Фактически указатель на указатель – это ячейка памяти, хранящая адрес указателя, при чем значение этого указателя (то есть адрес) может изменяться в ходе работы программы. При описании указатель на указатель может инициализироваться , например:

int data = 5; // переменная типа int

int *ptr = &data; // указатель 1-го уровня

int **ptr_ptr = &ptr; // указатель на указатель - 2-й уровень

Для доступа к переменной data в программе используется операция разадресации (*) – доступ к содержимому ячейки по указателю. Например, следующие выражения присваивают переменной data значение 10:

data = 10; // прямой доступ к переменной

*ptr = 10; // косвенный доступ к переменной

**ptr_ptr =10; // косвенный доступ через другой указатель к переменной, так как *ptr_ptr == &ptr

Для доступа к памяти через указатель на указатель можно использовать индексы, например, эквивалентны следующие ссылки на переменную data:

*ptr и ptr[0]; **ptr_ptr и ptr_ptr[0][0].

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

Пример 45.

Распечатать все строки символьного массива указателей на строки, используя указатель на указатель:

char *messages[ ] = { “Не открыт файл”,

“Ошибка ввода”,

“Диск”,

“Тайм-аут”,

0 } ; // признак конца массива

Программа:

#include<stdio.h>

#include<conio.h>

void main ()

{ char *messages [ ] = { // массив указателей

“Не открыт файл”,

“Ошибка ввода”,

“Диск “,

“Тайм-аут”,

0}; // признак конца массива

char **ptr_ptr = messages; //инициализация указателя на указатель

clrscr (); // очистка экрана

puts (“Вывод массива messages по строкам:”);

while ( *ptr_ptr ) // цикл, пока содержимое указателя строки не 0

puts ( *ptr_ptr++ ); // вывод строки и переход к новой строке

ptr_ptr=messages; // установка на начало массива указателей

puts (“\nПосимвольный вывод массива messages: ”)”;

while (*ptr_ptr) // цикл, пока содержимое указателя строки не 0

{ while (**ptr_ptr) // цикл, пока символ в строке не ‘\0’- конец строки

{ putchar (**ptr_ptr); // вывод символа из элемента массива

(*ptr_ptr)++; // получение адреса следующего элемента

}

ptr_ptr++; // переход указателя на следующую строку

printf(‘\n’); // переход на печать новой строки

}

puts (“Нажмите любую клавишу…”);

getch(); // задержка экрана

}

Результаты программы:

Вывод массива messages по строкам:

Не открыт файл

Ошибка ввода

Диск

Тайм-аут

Посимвольный вывод массива messages:

Не открыт файл

Ошибка ввода

Диск

Тайм-аут

Нажмите любую клавишу…