Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ЯП - ПОИТ (Бахтизин) часть 1 редакт.doc
Скачиваний:
0
Добавлен:
01.04.2025
Размер:
1.76 Mб
Скачать

7.3. Регистровый класс хранения (register)

В чем несомненный минус использования стека для хранения информации? Дело в том, что стек представляет собой специальный участок оперативной памяти, работа с которым осуществляется с использованием двух операций: push (помещения данных в стек) и pop (извлечения данных из стека). С одной стороны каждая из этих операций состоит из нескольких действий, с другой – работает с оперативной памятью, скорость доступа к которой ниже, чем скорость доступа к элементам памяти, расположенным внутри процессора. Значительно лучше было бы хранить переменные прямо в процессоре, а точнее – в его регистрах, это позволило бы сэкономить несколько тактов. В ситуациях, когда с переменной нужно проводить простые действия (например – побитовый сдвиг), хранение в регистре сократило бы работу в несколько раз. Поэтому локальные (не глобальные) переменные, используемые в счетчиках целесообразно хранить как регистровые. Количество доступных регистров ограничено архитектурой процессора и возможностями компилятора. Если регистров не хватает, компилятор игнорирует спецификатор register и переменная объявляется как автоматическая. По этой же причине без надобности регистры занимать не рекомендуется. Регистры не адресуются, поэтому к регистровым переменным неприменима операция взятия адреса.

Пример:

#include <stdio.h>

void main()

{

register long sum = 0;

for (register int i = 1; i <= 100; i++)

sum = sum + i;

printf("\nsum[100]=%d", sum);

}

Данная программа вычисляет и выводит на консоль сумму первых ста элементов арифметической прогрессии (1, 2, 3, 4,…).

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

7.4. Статический класс хранения (static)

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

Различают локальные и глобальные переменные статического класса хранения.

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

Пример:

#include <stdio.h>;

int print1(void);

int print2(void);

void main(void)

{

int i;

for (i = 1; i <= 5; i++)

{

printf("\n%d %d", print1(), print2());

}

}

int print1(void)

{

static int i = 0;

i++;

return i;

}

int print2(void)

{

int i = 0;

i++;

return i;

}

Все переменные здесь носят одно и то же имя – i, однако объявлены они по-разному: в функциях main и print2 объявлены автоматические переменные, которые при вызове функции возникают и инициализируются каждый раз вновь, а в print1 переменная объявлена как статическая, она сохраняет свое значение. Это приводит к тому, что на экран будет выведено следующее:

1 1

2 1

3 1

4 1

5 1

Не менее полезна и глобальная статическая переменная. Крупные программные проекты создаются группами из десятков и даже тысяч человек. Программа – это уже не один файл, а множество. Необходимо заботится о надежности такой системы, и один из способов – «связывание» переменных в файлах. Т.е., переменная, даже глобальная, видна только в файле, в котором объявлена, как следствие уменьшается риск случайного изменения переменной функциями из других файлов. Правда, «связывание» чаще применяется к функциям, для ограничения их использования другими файлами.

Необходимо сделать еще несколько замечаний по объявлению глобальных статических переменных: они автоматически инициализируются нулем, т.е., объявления static int i=0 и static int i будут эквивалентны; если глобальная переменная объявлена без спецификатора класса хранения, то этим классом по умолчанию будет статический, т.е., записи static int i и int i – эквивалентны.