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

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

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].

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

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

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:

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

Ошибка ввода

Диск

Тайм-аут

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


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: