Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Методичка по основам алгоритмизации и программи....doc
Скачиваний:
41
Добавлен:
02.11.2018
Размер:
2.69 Mб
Скачать

Описание переменных

Как видно из предытущего пункта, описание переменных может быть расположено в трех местах: внутри функции, в определении параметров функции и вне всех функций. Это  места объявлений соответсвенно локальных, формальных параметров функций и глобальных переменных.

Локальные переменные

Переменные, объявленные внутри функций, называются локальными переменными. Локальную переменную может быть доступна только внутри блока, в котором она определена, а за пределами своего блока она невидима. (Блок  это описания и инструкции, заключенные в фигурные скобки.)

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

Чаще всего локальные переменные используются в функциях. Рассмотрим, например, следующие две функции:

int main()

{

int x=1; // локальная переменная типа int

. . .

{ float x=1.2; // локальная переменная типа float

. . .

}

x = x+3; // локальная переменная типа int

return 0;

}

void fun() // функция fun

{

char x= ’a’; // локальная переменная типа char

. . .

}

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

При совпадении имен переменных, объявленных во внутреннем и внешнем (по отношению к нему) блоках, переменная внутреннего блока "маскирует" (т.е. делает невидимой) переменную внешнего блока. Рассмотрим следующий пример:

#include <stdio.h>

int main()

{ int x;

x = 1;

if(x == 1)

{ int x; // эта внутренняя x прячет внешнюю x

x = 2;

printf("Внутренняя x= %d\n", x);

}

printf("Внешняя x: %d\n", x);

return 0;

}

Результат выполнения программы следующий:

Внутренняя х= 2

Внешняя х = 1

В этом примере переменная х, объявленная внутри блока if, делает невидимой внешнюю переменную х. Следовательно, внутренняя и внешняя х  это два разных объекта. Когда блок заканчивается, внешняя переменная х опять становится видимой.

В стандарте С89 все локальные переменные должны быть объявлены в начале блока, до любого выполнимого оператора. Например, следующая функция вызовет ошибку компиляции в С89:

/* Эта функция вызывает ошибку компиляции

на компиляторе C89.

*/

void f(void)

{

int i;

i = 10;

int j; /* ошибка в этой строке */

j = 20;

}

Однако в С99 (и в C++) эта функция вполне работоспособна, потому что в них локальная переменная может быть объявлена в любом месте внутри блока до ее первого использования.

Так как локальные переменные создаются и уничтожаются при каждом входе и выходе из блока, их значение теряется каждый раз, когда программа выходит из блока. Это необходимо учитывать при вызове функции. Локальная переменная создается при входе в функцию и разрушается при выходе из нее. Это значит, что локальная переменная не сохраняет свое значение в период между вызовами (однако можно дать указание компилятору сохранить значение локальной переменной, для этого нужно объявить ее с модификатором static).

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

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

#include <stdio.h>

void f(void);

int main(void)

{

int i;

for(i=0; i<10; i++) f();

return 0;

}

void f(void)

{

int j = 10;

printf("%d ", j);

j++; /* этот оператор не влияет на результат */

}

Формальные параметры функции

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

/* Возвращает 1, если в строке s содержится символ c, в противном

случае возвращает 0 */

int is_in(char *s, char c)

{

while(*s)

if(*s==c) return 1;

else s++;

return 0;

}

Функция is_in() имеет два параметра: s и с, она возвращает 1, если символ, записанный в переменной с, входит в строку s, в противном случае она возвращает 0.

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

Глобальные переменные

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

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

#include <stdio.h>

int count; /* глобальная переменная count */

void func1(void);

void func2(void);

int main(void)

{

count = 100;

func1();

return 0;

}

void func1(void)

{

int temp;

temp = count;

func2();

printf("count равно %d", count); /* напечатает 100 */

}

void func2(void)

{

int count;

for(count=1; count<10; count++)

putchar('.');

}

Внимательно посмотрите на эту программу. Обратите внимание на то, что ни в func1(), ни в func2() нет объявления переменной count, однако они обе могут ее использовать. В func2() эта возможность не реализуется, так как в ней объявлена локальная переменная с тем же именем. Когда внутри func2() происходит обращение к переменной count, то это будет обращение к локальной, а не глобальной переменной. Таким образом, выполняется следующее правило: если локальная и глобальная переменные имеют одно и то же имя, то при обращении к ней внутри блока, в котором объявлена локальная переменная, происходит ссылка на локальную переменную, а на глобальную переменную это никак не влияет.

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