Классы памяти
Все переменные в программе характеризуются не только типом, но и классом памяти. В языке Си существует четыре класса памяти: автоматический (automatic), регистровый(register), статический(static) и внешний(external).
Автоматические переменные
Автоматические переменные в программе можно описать так:
auto A; auto char c1; auto int x= 125;
Если мы этим не пользовались, то только потому что опущенный описатель auto используется по умолчанию. Зона действия автоматической переменной ограничена блоком или функцией, где она описана. Она начинает существовать после обращения к функции и исчезает после выхода из нее. Таким образом автоматические переменные не занимают область в памяти. Значение автоматической переменной не может быть изменено другими функциями и в этих функциях может находится переменные с таким же именем. Проанализируем результаты работы следующей программы.
- #include <stdio.h>
- main()
- {
- int t;
- {
- int t=2;
- {
- int t=3;
- printf("%d\n",t);
- }
- printf("%d\n",t);
- }
- printf("%d\n",t);
- }
В этой программе перменная t описана в нескольких блоках, в каждом блоке она может принимать разные значения не зависимо от других. С ней могут выполнятся разные операции. В нашей програамме значение переменной t выводится на дисплей. В нашем случае выведятся числа 2, 3, 746. Число 746 - так называемое число "мусор" оно такое так как ей не присваивали значение в первом блоке.
Внешние переменные
Внешние переменные вводятся как нечто противоположное автоматическим. Это глобальные переменные и к ним можно обращаться именами из любой функции. Поскольку внешеие переменные доступны везде, их можно использовать для связи между функциями, не пренебрегая механизму формальных параметров.
- #include <stdio.h>
- int x=145;/*Описание внешней переменной*/
- main()
- {
- extern int x,y;
- printf("x=%d y=%d \n",x,y);
- }
- int y=541; /*Описание внешней переменной*/
Внешнии переменные могут определятся вне квкой-либо функции; при этом выделяется фактическая память. В любой другой функции, обращающейся к этим переменным, они должны описываться; делается явно с помощью описателя extern. Обычно поступают так, как показано на прмере 2.5. Все внешние переменные размещают в начале исходного модуля (вне всяких функций!), опуская дополнительные описания со словом extern внутри функций. Конечно, если внешняя переменная и функция, которая ее использует, размещены в разных файлах, описывать эту переменную в функции необходиммо. Но самым важным способом является описание каждой внешней перемнной с ключевого слова extern в любой функции, которая ее использует. А еще лучше избегать применения внешних переменных, так как они часто служат источником труднообнаруживаемых ошибок.
- int x=3; /*описание внешней переменной */
- /* увелечение x */
- int plus1()
- {
- x=x+1;
- printf("прибавляем единицу: x=%d\n",x);
- }
- /*уменьшение x */
- int mainus1()
- {
- x=x-1;
- printf("вычитаем единицу: x=%d\n",x);
- }
- main()
- {
- printf("начальное значение x=%d\n",x);
- plus1();
- minus1();
- minus1();
- printf("конечное значение x=%d \n", x);
- }
Статические переменные
Статические переменные, подобно автоматическим, локальны в той функции или блоке, где они описаны. Разница заключается в том, что статические переменные не исчезают, когда функция (блок) завершает работу, и их значения сохраняются для последующих вызовов функции. Описание статических переменных выглядит так:
static char c; static int a=1;
Рассмотрим следующий пример, в котором переменная объявлена как статическая
- /*статические переменные*/
- #include <stdio.h>
- plus1()
- {
- static int x=0;
- x=x+1;
- printf("x=%d\n",x);
- }
- main()
- {
- plus1();
- plus1();
- plus1();
- }
Начальное значение равное нулю присваивает переменной x только один раз. Затем в программе main, функция plus1() несколько раз запускается, так как при каждом запуске функции аргумент x не изменяется, а оставляет значение из предыдущей функции. Таким образом повторение функции plus1 обеспечивает увелечение переменной x на 1 при каждом запуске 1, 2, 3 ...
Регистровые переменные объявляются в программе с помощью ключевого слова register и по замыслу автора языка Си должны хранится в сверх быстрой памяти ЭВМ - регистрах. Используются аналогично автоматическим переменным. Целесообразность их применения для увелечения быстродействия программы представляется в большинстве случаев сомнительной.