Студопедия

КАТЕГОРИИ:


Архитектура-(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)

Auto, extern, register, static, mutable 6 страница




У деяких випадках модель пам'яті може вплинути на поведінку покажчиків і Ваші можливості з їх використання. Основна проблема виникає під час інкрементування покажчика за межі сегмента. Розгляд особливостей кожної з 16-розрядних моделей пам'яті виходить за рамки цього навчального посібника. Головне, щоб Ви знали, що, коли Вам доведеться працювати в 16-розрядному середовищі і орієнтуватися на процесори родини Intel 8086, програміст повинен вивчити документацію, що додається до використовуваного Вами компілятора, і детально розібратися в моделях пам'яті та їх впливі на покажчики.

І останнє. Під час написання програм для сучасного 32-розрядного середовища необхідно знати, що в ній використано єдину модель організації пам'яті, яка називається однорівневою, несегментованою або лінійною (flat model).

6.5.3. Багаторівнева непряма адресація

Можна створити покажчик, який посилатиметься на інший покажчик, а той – на кінцеве значення. Цю ситуацію називають багаторівневою непрямою адресацією (multiple indirection) або використанням покажчика на покажчик. Ідея багаторівневої непрямої адресації схематично проілюстрована на рис. 6.2. Як бачимо, значення звичайного покажчика (при однорівневій непрямій адресації) є адресою змінної, яка містить певне значення. У разі застосування покажчика на покажчик перший містить адресу другого, а той посилається на змінну, що містить певне значення.

Рис. 6.2. Однорівнева і багаторівнева непряма адресація

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

Змінну, яка є покажчиком на покажчик, потрібно оголосити відповідним чином. Для цього достатньо перед її іменем поставити додатковий символ "зірочка"(*). Наприклад, таке оголошення повідомляє компіляторові про те, що balance – це покажчик на покажчик на значення типу int:

int **balance;

Необхідно пам'ятати, що змінна balance тут – не покажчик на цілочисельне значення, а покажчик на покажчик на int -значення.

Щоб отримати доступ до значення, яка адресується покажчиком на покажчик, необхідно двічі застосувати оператор "*", як це показано в такому короткому прикладі.

Код програми 6.12. Демонстрація механізму використання багаторівневої непрямої адресації

#include <iostream> // Для потокового введення-виведення

using namespace std; // Використання стандартного простору імен

 

int main ()

{

int x *p, **q;

 

x = 10;

p = &x;

q = &p;

cout << **q; // Виводимо значення змінної х.

 

getch (); return 0;

}

У цій програмі змінна р оголошена як покажчик на int -значення, а змінна q – як покажчик на покажчик на int -значення. У процесі виконання цієї програми ми набудемо значення змінної х, тобто число 10.

6.6. Виникнення проблем під час використання покажчиків

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

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

Оскільки для багатьох працювати з покажчиками – означає потенційно приректи себе на пошуки відповіді на запитання "Хто винен?", ми спробуємо розглянути можливі "яри" на шляху відважного програміста і показати деякі обхідні шляхи, що дають змогу уникнути виснажливих "мук творчості".

6.6.1. Неініціалізовані покажчики

Класичний приклад помилки, що допускається під час роботи з покажчиками, – використання неініціалізованого покажчика. Розглянемо такий фрагмент коду програми:

// Ця програма некоректна

int main ()

{

int x, *p;

 

х = 10;

*p = х; //На що вказує змінна p?

 

getch (); return 0;

}

У цьому записі покажчик р містить невідому адресу, оскільки його ніде не визначено. У Вас немає можливості дізнатися, де записано значення змінної х. При невеликих розмірах програми (наприклад, як у цьому випадку) її особливості (які полягають у тому, що покажчик р містить адресу, що не належить ні коду програми, ні області даних) можуть ніяк не виявлятися, тобто програма зовні працюватиме нормально. Але у міру її удосконалення і, відповідно, збільшення її обсягу, імовірність того, що р стане вказувати або на код програми, або на область даних, зросте. Врешті-решт колись раптово програма взагалі перестане працювати. Спосіб не допустити розроблення таких програм очевидний: перш ніж використовувати покажчик, потурбуйтеся про те, щоб він посилався на що-небудь дійсне!

6.6.2. Некоректне порівняння покажчиків

Порівняння покажчиків, які не посилаються на елементи одного і того ж масиву, в загальному випадку є некоректним і часто призводить до виникнення помилок. Ніколи не варто покладатися на те, що різні об'єкти будуть розміщені в пам'яті якимсь певним чином (десь поряд) або на те, що всі компілятори і операційні середовища оброблятимуть Ваші дані однаково. Тому будь-яке порівняння покажчиків, які посилаються на різні об'єкти, може призвести до несподіваних наслідків. Розглянемо такий приклад:

char sMas[80];

char yMas [80];

char *p1, *р2;

 

p1 = sMas;

р2 = yMas;

if (p1 < р2).

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

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

int first [10];

int second [10];

int *p, t;

 

p = first;

for (t=0; t<20; ++t) {

*p = t;

p++;

}

 

Мета цієї програми – ініціалізувати елементи масивів first і second числами від 0 до 19. Проте цей програмний код не дає змогу сподіватися на досягнення бажаного результату, хоча у деяких умовах і під час використання певних компіляторів ця програма працюватиме так, як задумав автор. Не варто покладатися також на те, що масиви first і second будуть розташовані в пам'яті комп'ютера послідовно, причому першим обов'язково буде масив first. Мова програмування C++ не гарантує певного розташування об'єктів у пам'яті, і тому цю програму не можна вважати коректною.

6.6.3. Не встановлення покажчиків

Така (некоректна) програма повинна прийняти рядок, введений з клавіатури, а потім відобразити ASCII-код для кожного символу цього рядка[24]. Проте ця програма містить серйозну помилку.

Код програми 6.13. Демонстрація розроблення некоректної програми

#include <iostream> // Для потокового введення-виведення

#include <cstdio> // Для підтримки системи введення-виведення

#include <cstring> // Для роботи з рядковими типами даних

using namespace std; // Використання стандартного простору імен

 

int main ()

{

char sMas[80];

char *p1;

 

p1 = sMas;

do {

cout << "Введіть рядок: ";

gets (p1); // Зчитуємо рядок.

 

// Виводимо ASCII-значення кожного символу.

while (*p1) cout << (int) *p1++ " ";

cout << "\n";

} while (strcmp (sMas, "Кінець програми"));

 

getch (); return 0;

}

Чи зможете Ви самі знайти тут помилку?

У наведеному вище варіанті програми покажчику р1 присвоюється адреса масиву sMas тільки один раз. Це присвоєння виконується поза циклом. Під час входу в do-while -цикл (тобто при першій його ітерації) р1 дійсно вказує на перший символ масиву sMas. Але під час другого проходу того ж циклу р1 покажчик міститиме значення, яке залишиться після виконання попередньої ітерації циклу, оскільки покажчик р1 не встановлюється заново на початок масиву sMas. Рано чи пізно межу масиву sMas буде порушено.

Ось як виглядає коректний варіант тієї ж самої програми.

Код програми 6.14. Демонстрація розроблення коректної програми

#include <iostream> // Для потокового введення-виведення

#include <cstdio> // Для підтримки системи введення-виведення

#include <cstring> // Для роботи з рядковими типами даних

using namespace std; // Використання стандартного простору імен

 

int main ()

{

char sMas[80];

char *p1;

do {

p1 = sMas; // Встановлюємо p1 при кожній ітерації циклу.

cout << "Введіть рядок: ";

gets (p1); // Зчитуємо рядок.

 

// Виводимо ASCII-значення кожного символу.

while (*p1) cout << (int) *p1++ " ";

cout << "\n";

} while (strcmp (sMas, "Кінець програми"));

 

getch (); return 0;

}

Отже, у цьому варіанті програми на початку кожної ітерації циклу покажчик р1 встановлюється на початок рядка.

Необхідно пам'ятати! Щоб використання покажчиків було безпечним, потрібно у будь-який момент знати, на що вони посилаються.

 


Розділ 7. Основи застосування
С++-функцій

У цьому розділі поглиблено розглянуто функції – будівельні блоки мови програмування C++, а тому без повного їх розуміння неможливо стати успішним С++-програмістом. Ми вже торкнулися теми, яка стосується С++-функцій (див. розд. 2.3), і використали їх майже у кожному прикладі коду програми. У цьому розділі вони будуть розглядатися детальніше. Ця тема містить такі питання, як перегляд правил дії областей видимості функцій, рекурсивних функцій, деяких спеціальних властивостей функції main (), настанови return і прототипів функцій.

7.1. Правила дії областей видимості функцій

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

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

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

Як зазначалося вище, змінні, які оголошено всередині функції, називаються локальними. Але у мові програмування C++ передбачено "уважніше" відношення до локальних змінних, ніж ми могли помітити дотепер. У мові програмування C++ змінні можуть бути включені в блоки. Це означає, що змінну можна оголосити усередині будь-якого блоку коду програми, після чого вона буде локальною стосовно цього блоку[25]. Насправді змінні, локальні стосовно функції, утворюють просто спеціальний випадок більш загальної ідеї.

Локальну змінну можуть використовувати тільки настанови, включені в блок, у якому ця змінна оголошена. Іншими словами, локальна змінна невідома за межами власного блоку коду програми. Отже, записані поза блоком настанови не можуть отримати доступ до об'єкта, що визначається усередині блоку.

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

Найпоширенішим програмним блоком є функція. У мові програмування C++ кожна функція визначає блок коду програми, який починається з відкритої фігурної дужки цієї функції та завершується її закритою фігурною дужкою. Код функції та її дані – це її "приватна власність", і до неї не може отримати доступ жодна настанова з будь-якої іншої функції, за винятком настанови її виклику[26]. Тіло функції надійно приховане від решти частини програми і, якщо у функції не використовуються глобальні змінні, то вона не може зробити ніякого впливу на інші частини програми, однаково, як і ті на неї. Таким чином, вміст однієї функції зовсім незалежний від вмісту іншої. Іншими словами, програмні коди і дані, визначені в одній функції, не можуть взаємодіяти з кодами і даними, визначеними в іншій, оскільки дві функції мають різні області видимості.

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

Код програми 7.1. Демонстрація механізму використання області видимості локальних змінних

#include <iostream> // Для потокового введення-виведення

using namespace std; // Використання стандартного простору імен

void fun_1();

 

int main ()

{

char strMas[] = "Це масив strMas у функції main ().";

cout << strMas << "\n";

fun_1();

cout << strMas << "\n";

 

getch (); return 0;

}

 

void fun_1()

{

char strMas[80];

cout << "Введіть будь-який рядок: ";

cin >> strMas;

cout << strMas << "\n";

}

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

Мова C++ містить ключове слово auto, яке можна використовувати для оголошення локальних змінних. Але оскільки всі не глобальні змінні є за замовчуванням auto -змінними, то до цього ключового слова практично ніколи не вдаються. Тому Ви не знайдете у цьому навчальному посібнику жодного прикладу з його використанням. Але, якщо Ви захочете все-таки застосувати його у своїй програмі, то знайте, що розміщувати його потрібно безпосередньо перед типом змінної, як це показано нижче:

auto char ch;

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

Щоб краще зрозуміти зазначене вище, розглянемо таку програму:

Код програми 7.2. Демонстрація механізму використання області видимості локальних змінних стосовно блоку

#include <iostream> // Для потокового введення-виведення

#include <cstring> // Для роботи з рядковими типами даних

using namespace std; // Використання стандартного простору імен

 

int main ()

{

int vybir;

cout << "(1) додати числа або ";

cout << "(2) конкатенувати рядки?: ";

cin >> vybir;

if (vybir == 1) {

int a, b; // Активізуються дві int -змінні.

cout << "Введіть два числа: ";

cin >> а >> b;

cout << "Сума дорівнює " << a + b << "\n";

}

else {

char s1[80], s2[80]; // Активізуються два рядки.

cout << "Введіть два рядки: ";

cin >> s1;

cin >> s2;

strcpy (s1, s2);

cout << "Конкатенація дорівнює " << s1 << "\n";

}

getch (); return 0;

}

Ця програма, залежно від вибору користувача, забезпечує введення двох чисел або двох рядків. Звернемо Вашу увагу на оголошення змінних а і b в if -блоці і змінних s1 і s2 у else -блоці. Існування цих змінних почнеться з моменту входу у відповідний блок і припиниться відразу після виходу з нього. Якщо користувач вибере додавання чисел, будуть створені змінні а і b, а якщо він захоче конкатенувати рядки – то змінні s1 і s2. Нарешті, ні до однієї з цих змінних не можна звернутися ззовні їх блоку, навіть з частини коду програми, що належить тій самій функції. Наприклад, якщо Ви спробуєте скомпілювати наступну (некоректну) версію програми, то отримаєте повідомлення про помилку.

Код програми 7.2. Демонстрація некоректного звернення до локальних змінних

#include <iostream> // Для потокового введення-виведення

#include <cstring> // Для роботи з рядковими типами даних

using namespace std; // Використання стандартного простору імен

 

int main ()

{

int vybir;

cout << "(1) додати числа або ";

cout << "(2) конкатенувати рядки?: ";

cin >> vybir;

if (vybir == 1) {

int a, b; // Активізуються дві int -змінні.

cout << "Введіть два числа: ";

cin >> а >> b;

cout << "Сума дорівнює " << a + b << "\n";

}

else {

char s1[80], s2[80]; /* Активізуються два рядки. */

cout << "Введіть два рядки: ";

cin >> s1;

cin >> s2;

strcpy (s1, s2);

cout << "Конкатенація дорівнює " << s1 << "\n";

}

a = 10; // *** Помилка ***

// Змінна а тут невідома!

 

getch (); return 0;

}

Оскільки у цьому випадку змінна а невідома поза своїм if -блоком, компілятор видасть помилку під час спроби її використовувати.

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

Код програми 7.3. Демонстрація перевизначення "зовнішньої" змінної на "внутрішню"

#include <iostream> // Для потокового введення-виведення

using namespace std; // Використання стандартного простору імен

 

int main ()

{

int izm, jzm;

 

izm = 10; jzm = 100;

if (jzm > 0) {

int izm; // Ця змінна izm відокремлена від

// зовнішньої змінної izm.

izm = jzm / 2;

cout << "Внутрішня змінна izm: " << izm << "\n";

}

cout << "Зовнішня змінна izm: " << izm << "\n";

 

getch (); return 0;

}

Ось як виглядають результати виконання цієї програми.

Внутрішня змінна izm: 50

Зовнішня змінна izm: 10

Тут змінна izm, оголошена усередині if -блоку, перевизначає або приховує зовнішню змінну izm. Зміни, яким піддалася внутрішня змінна izm, не роблять ніякого впливу на зовнішню змінну izm. Понад це, поза if -блоком внутрішня змінна izm більше не існує, і тому зовнішня змінна izm знову стає видимою.

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

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

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

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

Код програми 7.4. Демонстрація місця оголошення змінних

#include <iostream> // Для потокового введення-виведення

using namespace std; // Використання стандартного простору імен

 

int main ()

{

cout << "Введіть число: ";

int a; // Оголошуємо одну змінну.

cin >> а;

cout << "Введіть друге число: ";

int b; // Оголошуємо ще одну змінну.

cin >> b;

cout << "Добуток дорівнює: " << a*b << "\n";

 

getch (); return 0;

}

У наведеному прикладі змінні а і b не оголошуються доти, доки вони стануть потрібними. Все ж таки більшість програмістів оголошують усі локальні змінні на початку блоку, у якому вони використовуються, але це, як мовиться, питання стилістики (або смаку).

7.1.2. Оголошення змінних в ітераційних настановах і настановах вибору

Змінну можна оголосити в розділі ініціалізації циклу for або умовних виразах таких настанов як if, switch або while. Змінна, оголошена в одній з цих настанов, має область видимості, яка обмежена блоком коду програми, керованим цією настановою. Наприклад, змінна, оголошена в настанові циклу for, буде локальною для цього циклу, як це показано в наведеному нижче прикладі:

#include <iostream> // Для потокового введення-виведення

using namespace std; // Використання стандартного простору імен

 

int main ()

{

// Змінна i локальна для циклу for.

for (int i=0; i<10; i++) {

cout << i << " ";

cout << "у квадраті дорівнює " << i * i << "\n";

}

// i = 10; // *** Помилка *** -- i тут невідома!

getch (); return 0;

}

У цій програмі змінну i оголошують в розділі ініціалізації циклу for і використовують для керування цим циклом. А за межами циклу змінна i невідома.

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

Необхідно пам'ятати! Твердження про те, що змінна, оголошена в розділі ініціалізації циклу for, є локальною стосовно цього циклу або не є такою, змінилося з часом (йдеться про час, протягом якого розвивалася мова C++). Спочатку така змінна була доступна після виходу з циклу for. Проте стандарт C++ обмежує область видимості цієї змінної рамками циклу for. Але необхідно мати на увазі, що різні компілятори і тепер по-різному "дивляться" на цю ситуацію.

Якщо Ваш компілятор повністю дотримується стандарту мови програмування C++, то Ви можете також оголосити змінну в умовному виразі настанов if, switch або while. Наприклад, у наведеному нижче коді програми

if (int x = 20) {

cout << "Це значення змінної х: ";

cout << х;

}

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




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


Дата добавления: 2014-11-29; Просмотров: 442; Нарушение авторских прав?; Мы поможем в написании вашей работы!


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



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




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