Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Л4. Оператори циклу_Вказ_вники.doc
Скачиваний:
2
Добавлен:
21.09.2019
Размер:
87.55 Кб
Скачать

Адреси даних. Вказівники. Динамічна пам'ять

1.Адреси даних.

Для розв'язування специфічних для мови C++ задач (робота з масивами, побудова графічних зображень і динамічних ефектів) потрібно знати не тільки значення деякої змінної, але й її адресу в оперативній пам'яті. Для визначення адреси даного у пам'яті є операція визначення адреси

&<назва даного>

Приклад 1. Розглянемо фрагмент програми

int a = 25;

cout << "Значення змінної а = " << а << "\n";

cout << "Адресою змінної а є " << &а;

У результаті виконання цих команд на екрані одержимо

Значення змінної а = 25 Адресою змінної а є xaf72254

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

2. Вказівники.

Змінні, значеннями яких є адреси ділянок пам’яті, називаються вказівниками. Вказівник вказує на початок області оперативної пам'яті комп'ютера, де зберігається дане. Вказівники дають змогу оперувати не з іменами даних, а безпосередньо звертатись до областей пам'яті комп'ютера

В С++ існує три види вказівників : 1)на об’єкти; 2)на функції; 3)на void.

1) Вказівник на об’єкти містить адреси діялнок пам’яті, де зберігаються значення певного типу. Формат запису наступний: <тип> *<ім’я вказівника>

Наприклад int *a, *b; float *c, *d;

Надати значення вказівникам можна так: <ім’я вказівника> = <адреса змінної>

Приклад. Нехай у програмі оголошені змінні

int n = 10;

float stud1, stud2, stud3;

Тоді можна визначити вказівники на ці змінні:

nomer = &n;

rist = &stud1;

rist = &stud3;

Вказівники застосовують, зокрема, для надання значень змінним:

rist = &stud1;

*rist = 1.85;

Тут вказівник rist вказуватимемо на адресу змінної stud1, a власне змінній stud1 буде присвоєно значення 1.85.

Вказівники можна переадресовувати. Зокрема, у прикладі вказівнику rist спочатку присвоєно адресу змінної stud1, а потім – адресу змінної stud3. Це правило не діє, якщо вказівник є сталою. Сталий вказівник, який вказує на одну і ту ж адресу, оголошують так:

const int *rik;

Для вказівників в залежності від ОС та версії компілятора резервується 2 або 4 байти в оперативній пам’яті.

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

Формат запису: <тип> (*<ім’я>) (список типів, агрументів)

Наприклад int (*abc) (double, double);

3) Вказівнику на void можна присвоїти значення будь-якого вказівника і порівнювати його з довільним вказівником, але перед виконанням будь-яких дій з ділянкою пам’яті, на яку він посилається, потрібно зводити його до вказівника на конкретний тип явним чином.

Особливо ефективною є робота з вказівниками на рядки та масиви.

3. Динамічна пам’ять.

Значення даних у пам’яті комп’ютера можна зберігати в області даних (статична пам’ять), у стеку або в динамічній пам’яті (heap-область , „на купі”). Під час оголошення статичних змінних система автоматично надає для зберігання їх значенб певний обсяг оперативної пам’яті, який залишається незмінним протягом всього часу виконання програми. Вивільняється пам’ять для статичних змінних лише після виконання програми. Тому в оперативній пам’яті можна розмістити обмежену кількість даних.

Проте є задачі, де наперед невідомо, скільки змінних потрібно для їх розв’язання (наприклад, опрацювання масивів великих розмірів). Тоді доцільно застосовувати динамічну організацію пам’яті.

Принцип динамічної організації пам’яті полягає в тому, що для змінних надається пам’ять за неоюхідністю (за вказівкою програміста). Далі ці змінні опрацьовуються і в потрібний момент часу вивільняються (за вказівкою програміста). Такі змінні називаються динамічними.

Для роботи з динамічними змінними використовують вказівники.

В С: функції динамічного виділення malloc() і free().

Функція malloc() виділяє пам’ять і повертає вказівник на початок виділеного блоку. Функція free() повертає раніше виділену пам’ять в купу для повторного використання.

В С++: для виділення динамічної пам’яті – команда new. Для звільнення пам’яті – delete.

Формат опису команди new: <тип вказівника> *<назва> = new<тип змінної>

Дія команди. Для відповідного типу змінної автоматично надається необхідна неперервна ділянка пам’яті. Команда new повертає обсяг цієї ділянки, а вказівник вказує на її початок. Наприклад, для даних цілого типу можна записати:

int *pr = new int;

Надати ділянку пам’яті і відразу занести в неї значення можна так:

int *pr1 = new float (2.71);

Таким чином, у адресу, на яку вказує pr1, буде занесено число 2,71/

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

Формат опису команди delete delete <назва вказівника>;

Щоб вказівник не вказував на жодну ділянку пам’яті його необхідно занулити командою <назва вказівника> = NULL;

або <назва вказівника> = 0.

Значенням (адресою) такого вказівника буде нульова адреса 0х00000000. Тут не може бути розміщене значення жодного даного.