Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
УМК-1_АЯП_рус.doc
Скачиваний:
0
Добавлен:
01.04.2025
Размер:
1.19 Mб
Скачать

Void main()

{ int a,b,*pa,*pb;

clrscr();

pa=&a; pb=&b;

printf("vvedi");

scanf("%d%d",pa,pb);

printf("\n a=%d b=%d ",*pa,*pb);

pa=pa+3;pb++;

*pa=20; *pb=30;

a=*pa;b=*pb;

printf("\n a=%d pa=%d b=%d pb=%d",a,*pa,b,*pb);

getch();

}

на экран монитора будут выведены следующие данные:

Vvedi 5 7

a=5 b=7

a=20 pa=20 b=30 pb=30

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

Все переменные в программе характеризуются не только типом, но и классом памяти. В языке Си существует четыре класса памяти: автоматический (automatic), регистровый(register), статический(static) и внешний(external).

Таблица 1

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

Класс памяти

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

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

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

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

auto

временно

блок

Регистровый

register

временно

блок

Статический

static

постоянно

блок

Внешний

extern

постоянно

программа

Автоматические переменные в программе можно описать так:

                                         auto A; auto char c1; auto int x= 125;

Если мы этим не пользовались, то только потому что опущенный описатель  auto используется по умолчанию. Зона действия автоматической переменной ограничена блоком или функцией, где она описана. Она начинает существовать после обращения к функции и исчезает после выхода из нее. Таким образом автоматические переменные не занимают область в памяти. Значение автоматической переменной не может быть изменено другими функциями и в этих функциях может находится переменные с таким же именем. Проанализируем результаты работы следующей программы.

Пример 1

#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 выводится на дисплей. В нашем случае выведятся числа 3, 2, 746. Число 746 - так называемое число "мусор" оно такое так как ей не присваивали значение в первом блоке.

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

   Пример 2

 #include <stdio.h> int x=145;/*Описание внешней переменной*/ main() {

extern int x,y;   printf("x=%d y=%d \n",x,y); }

Внешнии переменные могут определятся вне квкой-либо функции; при этом выделяется фактическая память. В любой другой функции, обращающейся к этим переменным, они должны описываться; делается явно с помощью описателя extern. Обычно поступают так, как показано на прмере 2. Все внешние переменные размещают в начале исходного модуля (вне всяких функций!), опуская дополнительные описания со словом extern внутри функций. Конечно, если внешняя переменная и функция, которая ее использует, размещены в разных файлах, описывать эту переменную в функции необходиммо. Но самым важным способом является описание каждой внешней перемнной с ключевого слова extern в любой функции, которая ее использует. А еще лучше избегать применения внешних переменных, так как они часто служат источником труднообнаруживаемых ошибок.

Пример 3.

int x=3; /*описание внешней переменной */ /* увелечение x */ int plus1() {    x=x+1;    printf("прибавляем единицу: x=%d\n",x); } /*уменьшение x */ int minus1() { x=x-1; printf("вычитаем единицу: x=%d\n",x); } main() {   printf("начальное значение x=%d\n",x);   plus1();   minus1();   printf("конечное значение x=%d \n", x); }

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

   static char c; static int a=1;

Рассмотрим пример 4, в котором переменная объявлена как статическая.

Пример 4

*статические переменные*/ #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 и по замыслу автора языка Си должны хранится в сверх быстрой памяти ЭВМ - регистрах. Используются аналогично автоматическим переменным.

Динамческое распределение памяти

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

- выделить память с запасом, если известно, например, что этих чисел гарантированно не более 1000.

- использовать динамическое выделение памяти – сначала определить, сколько чисел в массиве, а потом выделить ровно столько памяти, сколько нужно.

Наиболее грамотным решением является второй вариант (использование динамических массивов).

Динамческая память – это выделенная область памяти, которая может быть использована по мере необходимости.

Для работы с динамической памятью используются в основном две функции: функция выделения памяти - malloc() и функция освобождения памяти free().

Для выделения динамической памяти используется следующая запись:;

р=malloc(n*sizeof(тип_перменной));

где р – имя указателяь, который содержит адрес ячейки динамической памяти;

nчисло переменных, для которых выделяется память;

sizeof(тип_перменной) - размер типа переменной в байтах.

Например, в следующем примере захватывается участок динамической памяти размером в 4000 байтов, его адрес присваивается указателю на массив из 1000 целых чисел: