русс | укр

Мови програмуванняВідео уроки php mysqlПаскальСіАсемблерJavaMatlabPhpHtmlJavaScriptCSSC#DelphiТурбо Пролог

Компьютерные сетиСистемное программное обеспечениеИнформационные технологииПрограммирование


Linux Unix Алгоритмічні мови Архітектура мікроконтролерів Введення в розробку розподілених інформаційних систем Дискретна математика Інформаційне обслуговування користувачів Інформація та моделювання в управлінні виробництвом Комп'ютерна графіка Лекції


Область дії глобальних і локальних змінних


Дата додавання: 2014-04-22; переглядів: 1068.


Переважно більшість змінних програми має локальний час існування та локальну видимість, глобальними оголошують тільки окремі змінні, призначені для спільного використання. Діють такі правила:

1) змінні, оголошені на зовнішньому рівні (між функціями), частково глобальні – областю їх дії є частина програми від оголошення до кінця файлу;

2) змінні, оголошені на внутрішньому рівні (всередині програмного блоку), а також формальні параметри функцій мають область дії від точки оголошення до кінця функції (блоку);

3) змінні, що є параметрами прототипу функції, видимі тільки в межах цього прототипу;

4) якщо ім’я внутрішньої змінної збігається з іменем якогось зовнішнього об’єкту, то в межах цього блоку внутрішня змінна «закриває» зовнішній об’єкт, за межами блоку дія зовнішнього об’єкту відновлюється;

5) клас пам'яті змінних можна встановити явно, використовуючи відповідні специфікатори класів пам'яті.

Приклад програми:

 

#include <iostream>

using namespace std;

int main( ) {

int a = 2, b = 3;

{

int a = 4;

cout << a << endl; // 4

cout << b << endl; // 3

a = 123;

}

cout << a << endl; // 2

cout << b << endl; // 3

}

 

В цьому прикладі в програмі існують дві змінні з іменем а. Вони оголошені в рідних програмних блоках, тому під час компіляції програми помилки не виникає. Але у внутрішньому блоці внутрішня змінна а буде «закривати» зовнішню – на екран виводиться її значення, всі операції, зокрема a = 123; виконуються теж над нею. При виході з даного програмного блоку внутрішня змінна а видаляється з пам'яті, знову починаємо використовувати зовнішню змінну а.

Наступний приклад:

 

#include <iostream>

using namespace std;

int a = 1;

void test( void ) {

int a = 3;

cout << a << endl; // 3

}

int main( ) {

int a = 2;

cout << a << endl; // 2

test( );

}

 

Тут є три змінні з іменем а: одна глобальна, оголошена поза межами всіх функцій, і по одній в програмних блоках функцій main i test. При виконанні програми на екран будуть виводитися значення змінних, оголошення яких розташовані найближче до точки їх використання, тобто змінна а, оголошена в функції main, буде «закривати» глобальну змінну а, змінна а, оголошена в функції test, буде закривати змінну а із main. Видалимо оголошення змінної а з функції test:

 

#include <iostream>

using namespace std;

int a = 1;

void test( void ) {

cout << a << endl; // 1

}

int main( ) {

int a = 2;

cout << a << endl; // 2

test( );

}

 

Як і в попередньому прикладі, оголошення змінної а всередині функції main закриває глобальну змінну а. Але всередині функції test виконується звертання до глобальної змінної а. Змінна а з функції main в цьому програмному блоці не визначена. Це можна побачити, якщо видалити з цієї програми оголошення глобальної змінної а:

 

#include <iostream>

using namespace std;

void test( void ) {

cout << a << endl; // Помилка, змінна а не визначена

}

int main( ) {

int a = 2;

cout << a << endl;

test( );

}

 

Всередині функції test програма звертається до змінної а. Але в цьому програмному блоці така змінна не визначена, змінна а є внутрішньою змінної іншого програмного блоку.

1.68. Специфікатори класів пам'яті

Якщо в описі змінної специфікатор класів пам'яті відсутній, то клас пам'яті такої змінної встановлюється за правилами замовчування. В оголошеннях змінних специфікатор класів пам'яті вказують першим словом:

 

специфікатор_класу_пам'яті тип ім’я_змінної

 

В оголошеннях локальних змінних можна використовувати кожен з специфікаторів, наведених в таблиці 12.1. За замовчуванням таким змінним присвоюється клас пам'яті auto, вони зберігаються в області стека, виділеного для програми в оперативній пам'яті.

 

Таблиця 12.1. Сецифікатори класів пам'яті

Специфіка-тор Клас пам'яті Застосування Час існування Область дії Автоматична ініціалізація
Локальні змінні Глобальні змінні
auto автоматичний так ні локальний локальна відсутня
register регістровий так ні локальний локальна відсутня
static статичний так так глобальний локальна / частково глобальна ініціалізація нулем
extern зовнішній так так глобальний частково глобальна ініціалізація заборонена

 

Специфікатор register початково призначався тільки для змінних з типом int. Він вказував, що за наявності вільного системного регістра змінну слід зберігати в регістрі процесора, а не в оперативній пам'яті, як інші змінні. Застосування змінних дає змогу істотно скоротити час звертання до змінних, тому регістровий клас надають тим змінним, які найбільше впливають на загальну швидкодію програми. Оскільки кількість системних регістрів комп’ютера обмежена, то за відсутності вільних регістрів змінна з класом пам'яті register буде опрацьовуватись як звичайна локальна змінна з класом пам'яті auto.

Стандарт С-89 і С-99 розширили визначення специфікатора register. Тепер він може застосовуватись до змінних різних типів і означає, що доступ до цих змінних повинен бути настільки швидким, наскільки це можливо.

До регістрових змінних не можна застосовувати операцію взяття адреси. Якщо змінна зберігається в системному регістрі, то її адреса вважається неозначеною.

Застосування специфікатора static до локальних змінних змінює час існування цих змінних. Статичні змінні існують протягом всього часу виконання програми, але областю їх дії залишається блок, в якому вони оголошені. В наступному прикладі статична змінна використовується для підрахування кількості викликів функції.

 

#include <iostream>

using namespace std;

void test( void ) {

static int n;

cout << ++n << endl;

}

int main( ) {

for ( int i = 0; i < 5; i++ )

test( );

}

 

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

Специфікатор extern застосовують в оголошеннях локальних змінних щоб вказати, що ця змінна є посиланням на глобальну змінну з тим самим іменем і типом, описану далі в тексті програми або в іншому програмному файлі. Це робить зовнішню змінну доступною для звертання в межах даного програмного блоку.

 

#include <iostream>

using namespace std;

void test( void ) {

extern double PI;

cout << PI << endl;

}

double PI = 3.14159;

int main( ) {

test( );

}

 

Тут змінна РІ, оголошена в функції test не є самостійною змінною, а тільки посиланням на глобальну змінну РІ, яка в тексті програми описана нижче.


<== попередня лекція | наступна лекція ==>
Рекурсивні функції | Специфікатори глобальних змінних


Онлайн система числення Калькулятор онлайн звичайний Науковий калькулятор онлайн