Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Программирование / WORD / Лекции по ЯП (часть 3).doc
Скачиваний:
138
Добавлен:
15.04.2015
Размер:
1.34 Mб
Скачать

Классы памяти

При выборе класса памяти, т.е. способа хранения переменной в памяти при выполнении программы, может оказаться полезной следующая таблица, в которой сведены данные о пяти классах памяти в языке С.

Класс памяти

Ключевое слово

Время существования

Область действия

Автоматический

auto

временно

блок

Регистровый

register

временно

блок

Статический локальный

static

постоянно

блок

Статический глобальный

static

постоянно

файл

Внешний

extern

постоянно

программа

При выборе класса памяти, как правило, следует отдавать предпочтение автоматическим переменным, применяя остальные классы в случае необходимости. Вот еще некоторые рекомендации по назначению классов памяти.

  • Для начала сделайте все переменные автоматическими.

  • Если простая переменная должна использоваться очень интенсивно, например, как счетчик цикла, сделайте ее регистровой (добавьте к ее объявлению ключевое register).

  • В функциях, не являющихся main(), объявите статическими те переменные, которые должны сохранять свои значения между вызовами функций.

  • Если переменную используют все или почти все функции программы, сделайте ее внешней.

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

Указатель — это числовая переменная, содержащая адрес другой переменной. Указатель объявляется с помощью знака звездочки (*). Например,

int *ptr;

Для того чтобы указатель указывал на определенную переменную, ему присваивается ее адрес с помощью операции взятия адреса (&). Пусть объявлена переменная Var

int. Var

ptr = &Var; // инициализация указателя.

var = 12 и *ptr=12 идентичны.

Поскольку указатель и сам является числовой переменной, он располагается в памяти по определенному адресу. Поэтому можно создать указатель на указатель — переменную, которая содержит адрес переменной-указателя. Вот как это делается:

int var= 12; /* Var имеет тип int. */

int *ptr = &Var; /* ptr - указатель на Var. */

int **ptr_ptr = &ptr; /* ptr_to_ptr - указатель на указатель на int.*/

Обратите внимание, что при объявлении указателя на указатель используется двойной знак операции ссылки по указателю (**). Соответственно, он же используется для обращения к значению переменной по указателю на указатель:

**ptr to_ptr =12;

Этот оператор присваивает значение 12 переменной Var.

А следующий оператор отображает значение Var на экране: printf("*%d, **ptr_to_ptr);

Если по ошибке воспользоваться одинарной, а не двойной операцией ссылки применительно к указателю на указатель, то ничего хорошего из этого не выйдет. Например, следующий оператор присваивает значение 12 указателю ptr:

*ptr_to_ptr =12;

В результате ptr начинает указывать на некий адрес 12 в памяти компьютера. Очевидно, это ошибка с потенциально неприятными последствиями.

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

Самое распространенное применение указателей на указатели связано с массивами указателей.