АвтоАвтоматизацияАрхитектураАстрономияАудитБиологияБухгалтерияВоенное делоГенетикаГеографияГеологияГосударствоДомДругоеЖурналистика и СМИИзобретательствоИностранные языкиИнформатикаИскусствоИсторияКомпьютерыКулинарияКультураЛексикологияЛитератураЛогикаМаркетингМатематикаМашиностроениеМедицинаМенеджментМеталлы и СваркаМеханикаМузыкаНаселениеОбразованиеОхрана безопасности жизниОхрана ТрудаПедагогикаПолитикаПравоПриборостроениеПрограммированиеПроизводствоПромышленностьПсихологияРадиоРегилияСвязьСоциологияСпортСтандартизацияСтроительствоТехнологииТорговляТуризмФизикаФизиологияФилософияФинансыХимияХозяйствоЦеннообразованиеЧерчениеЭкологияЭконометрикаЭкономикаЭлектроникаЮриспунденкция

Многоуровневая адресация

Читайте также:
  1. Многоуровневая система высшего образования.
  2. Прямая адресация
  3. Тема «Компьютерные сети. Локальные, глобальные. Адресация в Интернете. Доменная система имен. Протоколы передачи данных TCP/IP. »

Массивы указателей

Как и объекты любых других типов, указатели могут быть собраны в массив. В следующем операторе объявлен массив из 10 указателей на объекты типа int:

int *x[10];

Для присвоения, например, адреса переменной var третьему элементу массива указателей, необходимо написать:

x[2] = &var;

В результате этой операции, следующее выражение принимает то же значение, что и var:

*x[2]

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

void display_array(int *q[])

{

int t;

for(t=0; t<10; t++)

printf("%d ", *q[t]);

}

Необходимо помнить, что q — это не указатель на целые, а указатель на массив указателей на целые. Поэтому параметрq нужно объявить как массив указателей на целые. Нельзя объявить q просто как указатель на целые, потому что он представляет собой указатель на указатель.

Массивы указателей часто используются при работе со строками. Например, можно написать функцию, выводящую нужную строку с сообщением об ошибке по индексу num:

void syntax_error(int num)

{

static char *err[] = {

"Нельзя открыть файл\n",

"Ошибка при чтении\n",

"Ошибка при записи\n",

"Некачественный носитель\n"

};

printf("%s", err[num]);

}

Массив err содержит указатели на строки с сообщениями об ошибках. Здесь строковые константы в выражении инициализации создают указатели на строки. Аргументом функции printf() служит один из указателей массива err, который в соответствии с индексом num указывает на нужную строку с сообщением об ошибке. Например, если в функциюsyntax_error() передается num со значением 2, то выводится сообщение Ошибка при записи.

Отметим, что аргумент командной строки argv (см. главу 6) также является массивом указателей на строковые константы.

Многоуровневая адресация

Иногда указатель может ссылаться на указатель, который ссылается на число. Это называется многоуровневой адресацией. Иногда применение таких указателей существенно усложняет программу, делает ее плохо читаемой и подверженной ошибкам. Рисунок иллюстрирует концепцию многоуровневой адресации. На рисунке видно, что значением "нормального" указателя является адрес объекта, содержащего нужное значение. В случае двухуровневой адресации первый указатель содержит адрес второго указателя, который содержит адрес объекта с нужным значением.



Многоуровневая адресация может иметь сколько угодно уровней, однако уровни глубже второго, т.е. указатели более глубокие, чем "указатели на указатели" применяются крайне редко. Дело в том, что при использовании таких указателей часто встречаются концептуальные ошибки из-за того, что смысл таких указателей представить трудно.

Переменная, являющаяся указателем на указатель, должна быть соответствующим образом объявлена. Это делается с помощью двух звездочек перед именем переменной. Например, в следующем операторе newbalance объявлена как указатель на указатель на переменную типа float:

float **newbalance;

Следует хорошо понимать, что newbalance — это не указатель на число типа float, а указатель на указатель на число типа float.

Указатель Переменная +--------+ +--------+ | Адрес |------->|Значение| +--------+ +--------+ Одноуровневая адресация Указатель Указатель Переменная+--------+ +--------+ +--------+| Адрес |----->| Адрес |----->|Значение|+--------+ +--------+ +--------+ Многоуровневая адресация
Рис. Одноуровневая и многоуровневая адресация

При двухуровневой адресации для доступа к значению объекта нужно поставить перед идентификатором две звездочки:

#include <stdio.h> int main(void){ int x, *p, **q; x = 10; p = &x; q = &p; printf("%d", **q); /* печать значения x */ return 0;}

Здесь p объявлена как указатель на целое, a q — как указатель на указатель на целое. Функция printf() выводит на экран число 10.


1 | 2 | 3 | 4 | 5 |


Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Студалл.Орг (0.006 сек.)