Студопедия

КАТЕГОРИИ:


Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748)

Глобальні і локальні визначення, простори імен та їх використання




Локальні змінні

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

Локальні змінні визначаються подібно до будь-яких інших змінних. Параметри, передані функції, гоже вважаються локальними змінними, і їх можна використовувати як визначені усередині тіла функції. У лістингу 5.2 представлений приклад використання параметрів функції і змінних, локально визначених усередині функції.

 

Лістинг 5.2. Використання локальних змінних u параметрів функції

1: #include <iostream.h>

2:

3: float Convert(float);

4: int main()

5: {

6: float TempFer;

7: float TempCel;

8:

9: cout << "Please enter the temperature in Fahrenheit: ";

10: cin >> TempFer;

11: TempCel = Convert(TempFer);

12: cout << "\nHere's the temperature in Celsius: ";

13: cout << TempCel << endl;

14: return 0;

15: }

16:

17: float Convert(float TempFer)

18: {

19: float TempCel;

20: TempCel = ((TempFer - 32) * 5) / 9;

21: return TempCel;

22: }

 

Результат:

Please enter the temperature in Fahrenheit: 212

Here's the temperature in Celsius: 100

Please enter the temperature in Fahrenheit: 32

Here's the temperature in Celsius: 0

Please enter the temperature in Fahrenheit: 85

Here's the temperature in Celsius: 25.4444

 

Аналіз: В рядках 6 і 7 оголошуються дві змінні типу float: одна (TempFer) для зберігання значення температури в градусах за Фаренгейтом, а інша (TempCel) - в градусах за Цельсієм. У рядку 9 користувачеві пропонується ввести температуру за Фаренгейтом, і це значення потім передається функції Convert().

Після виклику функції Convert() програма продовжує виконання з першого вираження в тілі цієї функції, представленого рядком 19, де оголошується локальна змінна, також названа TempCel. Зверніть увагу, що ця локальна змінна - не та ж сама змінна TempCel, яка оголошена в рядку 7. Ця змінна існує тільки усередині функції Convert(). Значення, передане як параметр TempFer, також є лише переданим з функції main() локальною копією однойменної змінної.

 

У функції Convert() можна було б задати параметр FerTemp і локальну змінну CelTemp, що не вплинуло б на роботу програми. Щоб переконатися в цьому, можете ввести нові імена і перекомпілювати програму.

 

Локальній змінній TempCel привласнюється значення, яке виходить в результаті виконання наступних дій,: віднімання числа 32 з параметра TempFer, множення цієї різниці на число 5 з наступним діленням на число 9. Результат обчислень потім повертається як значення повернення функції, і в рядку 11 воно привласнюється змінній TempCel функції main(). В рядку 13 це значення виводиться на екран.

У нашому прикладі програма запускалася тричі. Вперше вводиться значення 212, щоб переконатися в тому, що точка кипіння води за Фаренгейтом (212) згенерує правильну відповідь в градусах Цельсія (100). При другому випробуванні вводиться значення точки замерзання води. Утретє - випадкове число, вибране для отримання дробового результату.

Як приклад спробуйте запустити програму знову з іншими іменами змінних, як показано нижче.

Повинен вийти той же результат.

Кожна змінна характеризується своєю зоною видимості, що визначає час життя і доступність змінної в програмі. Змінні, оголошені усередині деякого блоку програми, мають зону видимості, обмежену цим блоком. До них можна дістати доступ тільки в межах цього блоку, і після того, як виконання програми вийде за межі, усі його локальні змінні автоматично видаляються з пам'яті. Глобальні ж змінні мають глобальну зону видимості і доступні з будь-якої точки програми.

 

1: #include <iostream.h>

2:

3: float Convert(float);

4: int main()

5: {

6: float TempFer;

7: float TempCel;

8:

9: cout << "Please enter the temperature in Fahrenheit: ";

10: cin >> TempFer;

11: TempCel = Convert(TempFer);

12: cout << "\nHere's the temperature in Celsius: ";

13: cout << TempCel << endl;

14: return 0;

15: }

16:

17: float Convert(float Fer)

18: {

19; float Cel;

20; Cel = ((Fer - 32) * 5) / 9;

21: return Cel;

22: }

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

Глобальні змінні

Змінні, визначені поза тілом якої-небудь функції, мають глобальну зону видимості і доступні з будь-якої функції в програмі, включаючи main().

Локальні змінні, імена яких співпадають з іменами глобальних змінних, не змінюють значень останніх. Проте така локальна змінна приховує глобальну змінну. Якщо у функції є змінна з тим же ім'ям, що і у глобальної, то при використанні усередині функції це ім'я відноситься до локальної змінної, а не до глобальної. Це проілюстровано в лістингу 5.3.

Лістинг 5.3. Демонстрація використання їло глобальних і локальних змінних

 

1: #include <iostream.h>

2: void myFunction(); // прототип

3:

4: int x = 5, у = 7; // глобальні змінні

5: int main()

6: {

7:

8: cout << "x from main: " << x << "\n";

9: cout << "у from main; " << у << "\n\n";

10: myFunction();

11: cout << "Back from myFunction!\n\n";

12: cout << "x from main: " << x << '\n";

13: cout << "y from main: " << y << "\n";

14: return 0;

15: }

16:

17: void myFunction()

18: {

19: int y = 10;

20:

21: cout << "x from myFunction: " << x << "\n";

22: cout << "y from myFunction: " << y << "\n\n";

23: }

 

Результат:

x from main: 5

y from main: 7

x from myFunction: 5

y from myFunction: 10

Back from myFunction!

x from main: 5

y from main: 7

Аналіз: Ця проста програма ілюструє декілька ключових моментів, пов'язаних з використанням локальних і глобальних змінних, на яких часто спотикаються початкуючі програмісти. У рядку 4 оголошуються дві глобальні змінні - x і у. Глобальна змінна x ініціалізувалася значенням 5, глобальна змінна у - значенням 7.

У рядках 8 і 9 у функції main() ці значення виводяться на екран. Зверніть увагу, що хоча ці змінні не оголошуються у функції main(), вони і такі доступні, будучи глобальними.

При виклику в рядку 10 функцій myFunction() виконання програми триває з рядка 18, а в рядку 19 оголошується локальна змінна у, яка ініціалізувалася значенням 10. У рядку 21 функція myFunction() виводить значення змінної x. При цьому використовується глобальна змінна x, як і у функції main(). Проте в рядку 22 при зверненні до змінної у на екран виводиться значення локальної змінної у, тоді як глобальна змінна з таким же ім'ям виявляється прихованою.

Після завершення виконання тіла функції управління програмою повертається функції main(), яка знову виводить на екран значення тих же глобальних змінних. Зверніть увагу, що на глобальну змінну у абсолютно не вплинуло привласнення значення локальній змінній у функції myFunction().

Глобальні змінні; будьте напоготові

Слід зазначити, що в C++ глобальні змінні майже ніколи не використовуються. Мова C++ виросла із З, де використання глобальних змінних завжди було багате наслідками виникненням помилок, хоча обійтися без їх застосування також було не можливо. Глобальні змінні потрібні в тих випадках, коли програмістові треба зробити дані доступними для багатьох функцій, а передавати дані з функції у функцію як параметри проблематично.

Небезпека використання глобальних змінних виходить з їх загальнодоступності, внаслідок чого одна функція може змінити значення змінної непомітно для іншої функції. У таких ситуаціях можлива поява помилок, які дуже важко виявити.

Стандартний простір імен std

Найкращий приклад просторів імен можна знайти в стандартній бібліотеці C++. Усі функції, класи, об'єкти і шаблони стандартної бібліотеки оголошені усередині простору імен std.

Ймовірно, вам доводилося бачити подібні вирази:

##include <iostream>

using namespace std;

Не забувайте, що використання директиви using відкриває доступ до усіх ідентифікаторів іменованого простору імен. Тому краще не звертатися до допомоги цього оператора при роботі із стандартними бібліотеками. Чому? Та тому, що таким чином ви порушите основне призначення просторів імен. Глобальний простір буде буквально заповнений іменами різних ідентифікаторів з файлів заголовків стандартної бібліотеки, велика частина яких не використовується в цій програмі. Пам'ятайте, що в усіх файлах заголовків використовується засіб простору імен, тому, якщо ви включите в програму декілька файлів заголовків і використаєте оператор using, усі ідентифікатори, оголошені в цих файлах заголовків, отримають глобальну видимість. Ви могли помітити, що в більшості прикладів цієї книги це правило порушується. Це зроблено виключно скорочено викладу прикладів. Вам же слід використовувати у своїх програмах оголошення з ключовим словом using, як в наступному прикладі:

 

##include <iostream>

using std::cin;

using std::cout;

using std::endl;

int main()

{

int value = 0;

cout << "So, how many eggs did you say you wanted"? << endl;

cin >> value;

cout << value << " eggs, sunny - side up"! << endl;

return(0);

}

 

Виконання цієї програми приведе до наступного висновку:

So, how many eggs did you say you wanted?

4 eggs, sunny - side up!

 

Як альтернатива можна явно звертатися до ідентифікаторів, оголошених в просторі імен,:

##include <iostream>

int main()

{

int value = 0;

std::cout << "How many eggs did you want"? << std::endl;

std::cin >> value;

std::cout << value << " eggs, sunny - side up"! << std::endl;

 

return(0);

}

 

Програма виведе наступні дані:

How many eggs did you want?

4 eggs, sunny - side up!

 

Такий підхід цілком годиться для невеликої програми, але у великих застосуваннях буде досить складно простежити за усіма явними зверненнями до ідентифікаторів простору імен. Тільки уявіть собі: вам доведеться додавати std:: для кожного імені із стандартної бібліотеки!

Резюме

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

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

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

 




Поделиться с друзьями:


Дата добавления: 2013-12-14; Просмотров: 943; Нарушение авторских прав?; Мы поможем в написании вашей работы!


Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет



studopedia.su - Студопедия (2013 - 2024) год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! Последнее добавление




Генерация страницы за: 0.047 сек.