Локальная переменная в программировании

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

Напомним, что каждый модуль (процедура, функция, программа) состоит из заголовка ( procedure . , function . , program . ) и блока.

Если блок какой-либо процедуры p1 содержит внутри процедуру p2 , то говорят, что p2 вложена в p1 . Пример:

procedure p1(x: real; var y: real); var c: integer; procedure p2(var z: real); . end; begin . end;

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

procedure t1; var y1, y2: real; procedure sq1; var a, b, c, d: real; begin < Переменные a, b, c, d являются локальными для sq1, область их действия – процедура sq1 >. end; begin < Переменные y1, y2 - нелокальные для sq1, область их действия – t1 и sq1 >. end;

Константы, переменные, типы, описанные в блоке program , называются глобальными. Казалось бы, проще иметь дело вообще только с глобальными переменными, описав их все в основной программе. Но использование локальных переменных позволяет системе лучше оптимизировать программы, делать их более наглядными и уменьшает вероятность появления ошибок.

При написании программ, имеющих вложенные модули, необходимо придерживаться следующих правил:

  1. Описывать идентификаторы в том блоке, где они используются, если это возможно.
  2. Если один и тот же объект (переменная, тип, константа) используются в двух и более блоках, то описать этот объект надо в самом внешнем из них, содержащем все остальные блоки, использующие данный объект.
  3. Если переменная, используемая в процедуре, должна сохранить свое значение до следующего вызова этой процедуры, то такую переменную надо описать во внешнем блоке, содержащем данную процедуру.
Читайте также:  Язык программирования php основы php

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

var k: integer; procedure a; var x, z: real; begin < через x, z обозначены две величины – локальные переменные для a; k – глобальная переменная для a >. end; procedure b; var x, y: integer; begin < через x, y обозначены две другие величины – локальные переменные для b; k – глобальная переменная для b >. end; begin < k – единственная переменная, которую можно использовать в основной ветке программы >. end.

Если один и тот же идентификатор описан в блоке b и второй раз описан во вложенном в b блоке c , то надо помнить, что эти два одинаковых идентификатора соответствуют разным ячейкам памяти.

var i: integer; a: real; procedure p(var d: real); var i: integer; begin i := 3; d := i + 10 * d; end; begin a := 2.0; i := 15; p(a); writeln(' i = ', i, ' a = ', a); end.

Глобальным переменным i и a отводятся две ячейки памяти. Первыми выполняются операторы a := 2.0 и i := 15 . Затем вызывается процедура p(a) . В процессе работы p отводится ячейка для локальной переменной i и туда засылается число 3. После окончания работы процедуры p эта ячейка i программой «забывается». После возврата на оператор writeln программа знает только одну ячейку i – глобальную, т.е. ту, которая содержит число 15. Поэтому программа выдаст на печать i = 15, a = 23.0 , т.к. a = 3 + 10 * 2 .

Если локальная и глобальная переменная принадлежат к одному и тому же сложному типу, то этот тип надо описать в разделе type , а сами переменные описывать через этот общий тип.

type ab = array[1..3] of real; var a: ab; procedure q; var b: ab; . end;

В этом примере переменные a и b описаны через общий тип ab . Если же локальная и глобальная переменные описаны одинаково, но не через общий тип, то программа может «не понять», что эти переменные принадлежат одному типу.

var a: array[1..3] of real; procedure q; var b: array[1..3] of real; . end;

В этом примере переменные a и b – одинаковые массивы, т.е. типы этих переменных одинаковы, но программа, тем не менее, «не считает», что a и b принадлежат одному типу. Это происходит из-за того, что описание массивов дано в разных блоках.

Источник

Область видимости объектов

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

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

Время жизни объекта может быть глобальным и локальным.

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

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

#include
void autofunc( void )
int k = 1; // локальный объект
printf( » \n k = %d » , k);
k = k + 1;
>
int main()
for ( int i = 0; i autofunc();
getchar();
return 0;
>

Область видимости локальной переменной k — функция autofunc() . Каждый раз при входе в функцию с идентификатором k ассоциируется некоторая ячейка памяти, в которую помещается значение равное 1.

Локальная переменная k

Результат выполнения программы

Та же программа, но с использованием глобального объекта

#include
int k = 1; // глобальный объект
void autofunc( void )
printf( » \n k = %d » , k);
k = k + 1;
>
int main()
for ( int i = 0; i autofunc();
getchar();
return 0;
>

Глобальная переменная k

Результат выполнения программы

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

#define _CRT_SECURE_NO_WARNINGS
#include
int x, y, z; // глобальные переменные
void sum( void )
z = x + y;
>
int main()
printf( «x= » );
scanf( «%d» , &x);
printf( «y= » );
scanf( «%d» , &y);
sum();
printf( «z= %d» , z);
getchar(); getchar();
return 0;
>

Использование глобальных переменных

Результат выполнения

Модификация объектов

Модификация или видоизменение объектов в языке Си применяется для того, чтобы изменить диапазон значений или область действия объекта. Ключевые слова, которые применяются для модификации, называются модификаторами .

Модификатор unsigned предназначен для того, чтобы объявлять беззнаковую целочисленную переменную, тем самым изменив диапазон представления этой переменной.

Модификатор extern предназначен для использования в данном программном модуле объекта, который объявлен в другом программном модуле.

#define _CRT_SECURE_NO_WARNINGS
#include
int x, y, z;
extern void func( void );
int main()
printf( «x= » );
scanf( «%d» , &x);
printf( «y= » );
scanf( «%d» , &y);
func();
printf( «z= %d» , z);
getchar(); getchar();
return 0;
>

Модификатор extern

Пример окна проекта, состоящего из двух файлов

Модификатор static позволяет связать с идентификатором фиксированный адрес (ячейку памяти). Если объект расположен по некоторому фиксированному адресу, то он называется статическим .

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

#include
void autofunc( void )
static int k = 1; // статический объект
printf( » \n k = %d » , k);
k = k + 1;
>
int main()
for ( int i = 0; i autofunc();
getchar();
return 0;
>

Переменная k в функции autofunc() зафиксирована в оперативной памяти. Инициализация k проводится только один раз — при первом вызове функции. При повторном обращении к функции autofunc() инициализация переменной k не будет производиться. Значение переменной k и ее адрес сохраняются в оперативной памяти, однако эта переменная не будет доступна из других функций.

Статическая переменная k

Результат выполнения программы

Модификатор register предназначен для того, чтобы поместить переменную в один из регистров общего назначения центрального процессора при наличии свободного регистра. Благодаря этому повышается скорость работы с данными. Это необходимо для создания управляющих программ, где требуется высокая скорость обработки данных.

Комментариев к записи: 3

Источник

Локальная переменная в программировании

Каждая переменная имеет определенную область видимости (scope). Область видимости представляет участок программы, в рамках которого можно использовать переменную.

Переменные бывают глобальными и локальными или автоматическими.

Локальные автоматические переменные

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

#include void printn() < int n = 63; printf("n=%d \n", n); >int main(void) < int a = 2; printn(); // n=63 //n++; так сделать нельзя, так как n определена в функции printn printf("a=%d \n", a); // a=2 return 0; >

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

То же самое касается переменных, которые определены во вложенных блоках кода, например, условных конструкциях if..else, switch..case, циклах for,while, do..while. Например:

void printn() < < int n = 20; // локальная переменная printf("%d \n", n); >printf("%d \n", n); // Ошибка - здесь переменная n не видна >

Здесь переменная n по прежнему является локальной и автоматической. Но она определена не просто в функции, а в блоке кода внутри функции. И вне этого блока кода даже внутри функции ее нельзя использовать, потому что после завершения блока кода она удаляется.

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

Глобальные переменные определены в файле программы вне любой из функций и могут использоваться любой функцией из этого файла.

#include int n = 5; void printn() < n++; printf("n=%d \n", n); >int main(void) < printn(); // n=6 n++; printf("n=%d \n", n); // n=7 return 0; >

Здесь переменная n является глобальной и доступна из любой функции. При этом любая функция может изменить ее значение.

Сокрытие переменных

Автоматические переменные, определенные внутри блока кода, могут скрывать внешние переменные с тем же именем:

#include int n = 5; int main(void) < int n = 10; printf("n=%d \n", n); // n=10 < int n = 20; printf("n=%d \n", n); // n=20 >return 0; >

Здесь определено три переменных с именем n . Автоматическая переменная n, определенная на уровне функции main ( int n = 10; ) скрывает глобальную переменную n. А переменная n, определенная на уровне блока, скрывает переменную, определенную на уровне функции main.

Статические переменные

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

Например, пусть у нас будет функция со стандартной автоматической переменной:

#include void display() < int i = 0; i++; printf("i=%d \n", i); >int main(void)

Функция display вызывается три раза, и при каждом вызове программа повторно будет выделять память для переменной i, которая определена в функции. А после завершения работы display, память для переменной i будет освобождаться. Соответственно ее значение при каждом вызове будет неизменно:

Теперь сделаем переменную i статической:

#include void display() < static int i = 0; i++; printf("i=%d \n", i); >int main(void)

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

Регистровые переменные

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

Ключевое слово register применяется к переменным:

void display(register int a)

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

Источник

Оцените статью