Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
+ООП_Навч_посібник.doc
Скачиваний:
8
Добавлен:
01.07.2025
Размер:
6.58 Mб
Скачать

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++ не гарантує певного розташування об'єктів у пам'яті, і тому цю програму не можна вважати коректною.