Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
lek6_cpp_ukr.rtf
Скачиваний:
4
Добавлен:
18.11.2019
Размер:
340.33 Кб
Скачать

10

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

1. Основні відомості про вказівники

       В результаті процесу компіляції програми всі імена змінних будуть перетворені в адреси комірок пам'яті, в яких містяться відповідні значення даних. У командах машинної програми при цьому знаходяться машинні адреси розміщення значень змінних. Саме це і є пряма адресація - виклик значення за адресою в команді. Наприклад, в операторі присвоювання: k = j на машинному рівні відбувається копіювання значення з області ОП, що відведена змінній j, в область ОП, яка відведена змінній k. Таким чином, при виконанні машинної програми реалізуються операції над операндами - значеннями змінних, розташованими за визначеними адресами ОП. На машинному рівні імена змінних у командах не використовуються, а тільки адреси, сформовані транслятором з використанням імен змінних. Проте програміст не має доступу до цих адрес, якщо він не використовує вказівники.

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

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

       Тип змінної, що адресується, може бути стандартний, нумерований, структурний, об'єднання або void. Вказівник на тип void може адресувати значення будь-якого типу. Розмір пам'яті для самого вказівника і формат збереженої адреси (вмісту вказівника) залежить від типу комп'ютера та обраної моделі пам'яті. Константа NULL зі стандартного файлу stdio.h призначена для ініціалізації вказівників нульовим (незайнятим) значенням адреси.

       Змінна типу вказівник оголошується подібно звичайним змінним із застосуванням унарного символу "*". Форма оголошення змінної типу вказівник наступна:

       тип [модифікатор] * імені-вказівника ;

де тип - найменування типу змінної, адресу якої буде містити змінна-вказівник (на яку він буде вказувати).

       Модифікатор необов'язковий і може мати значення:

   • near - ближній, 16-бітний вказівник (встановлюється за замовчуванням), призначений для адресації 64-кілобайтного сегмента ОП;

   • far - дальній, 32-бітний вказівник, містить адресу сегмента і зсув у ньому: може адресувати ОП обсягом до 1 Мб;

   • huge - величезний, аналогічний вказівнику типу far, але зберігається у нормалізованому форматі, що гарантує коректне виконання над ним операцій; застосовується до функцій і до вказівників для специфікації того, що адреса функції або змінної, що адресується, має тип huge;

   • імені-вказівника - ідентифікатор змінної типу вказівник;

   • визначає змінну типу вказівник.

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

       Нижче наведено приклади деяких можливих оголошень вказівників:

int *pi; /* - вказівник - змінна на дані типу int */ float *pf; /* - вказівник - змінна на дані типу float */ int ml [5]; /* - ім'я масиву на 5 значень типу int; ml - вказівник-константа, про це йтиметься згодом */ int *m2[10]; /* m2 - ім'я масиву на 10 значень типу вказівник на значення типу int, m2 - вказівник-константа */ int (*m3)[10]; /* - вказівник на масив з 10 елементів типу int; m3 - вказівник-константа */

       Зверніть увагу на те, що у трьох з наведених оголошень ім'я масиву є константою - вказівником!

       За допомогою вказівників, наприклад, можна:

1. обробляти одновимірні та багатовимірні масиви, рядки, символи, структури і масиви структур;

2. динамічно створювати нові змінні в процесі виконання програми;

3. обробляти зв'язані структури: стеки, черги, списки, дерева, мережі;

4. передавати функціям адреси фактичних параметрів;

5. передавати функціям адреси функцій в якості параметрів.

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

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]