Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекція 4 (Покажчики).docx
Скачиваний:
20
Добавлен:
16.05.2015
Размер:
86.31 Кб
Скачать

ПОКАЖЧИКИ

Основні відомості про покажчики

        В результаті процесу компіляції програми всі імена змінних будуть перетворені в адреси комірок пам'яті, в яких містяться відповідні значення даних. У командах машинної програми при цьому знаходяться машинні адреси розміщення значень змінних. Саме це і є пряма адресація - виклик значення за адресою в команді. Наприклад, в операторі присвоювання: 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 - покажчик-константа */

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

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

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

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

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

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

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

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

Моделі пам'яті

        Взагалі ОП для виконання програми на мові Сі використовується для:

  • розміщення програми (коду програми);

  • розміщення зовнішніх (глобальних) і статичних даних (що мають специфікатори extern і static, про них йтиметься нижче);

  • динамічного використання ОП для змінних, сформованих у процесі виконання програми (купа, динамічна ОП, про них йтиметься нижче);

  • для розміщення локальних (auto - автоматичних) змінних, змінних функцій (стек) під час виконання програми.

Структура оперативної пам'яті

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

У мові Сі розмір ОП (оперативної пам'яті) для розміщення покажчика залежить від типу використаної моделі пам'яті. У програмах на мові Сі можна використовувати одну з шести моделей пам'яті.

Крихітна (tiny model) ОП. Модель пам'яті використовується при дефіциті ОП. Для коду програми, статичних даних, динамічних даних (купи) та стеку виділяється 64 Кб. Змінна - покажчик типу near (ближній) займає 2 байти.

Мала (small model) ОП. Для програми призначається 64 Кб. Стек, купа і статичні дані займають по 64 Кб. Ця модель приймається за замовчуванням та використовується для вирішення маленьких і середніх задач. Покажчик типу near займає 2 байти і містить адресу - зсув усередині сегмента ОП з 64 Кб.

Середня (medium model) ОП. Розмір ОП для програми дорівнює 1 Мбайт. Стек, купа і статичні дані розміщаються в сегментах ОП розміром 64 Кб. Цю модель застосовують для дуже великих програм і невеликих обсягів даних. Покажчик у програмі типу far займає 4 байти. Для адресації даних покажчик типу near займає 2 байти.         Компактна (compact model) ОП. Для програми призначається 64 Кб. Для даних - 1 Мбайт. Об'єм статичних даних обмежується 64 Кб. Розмір стека повинен бути не більш 64 Кб. Ця модель використовується для малих і середніх програм, що вимагають великого об'єму даних. Покажчики в програмі складаються з 2 байтів, а для даних - з 4 байтів.

Велика (large model) ОП. ОП для програми обмежена 1 Мб. Для статичних даних призначається 64 Кб. Купа може займати до 1 Мб. Програма і дані адресуються покажчиками, що займають 4 байти. Використовується для великих задач. Окрема одиниця даних, наприклад масив, повинна займати не більш 64 Кб.

Величезна (huge model) ОП. Аналогічна великій моделі. Додатково в ній знімається обмеження на розмір окремої одиниці даних.

Вид моделі пам’яті

Про­грама

Стек

Купа (динаміч­ні дані)

Статич­ні дані

Коли використовують

Тип і розмір покажчика

Крихітна

(tiny model)

64 Кб

При дифіциті пам’яті

near – 2б

Мала

(small model)

64 Кб

64 Кб

64 Кб

64 Кб

Для маленьких і середніх задач

near – 2б

Середня (medium model)

1 Мб

64 Кб

64 Кб

64 Кб

для дуже великих програм і невеликих обсягів даних

near – 2б

Компактна (compact model)

64 Кб

64 Кб

1 Мб

64 Кб

для малих і середніх програм, що вимагають великого об'єму даних

для програми

near – 2б

для даних

far - 4б

Велика

(large model)

1 Мб

64 Кб

1 Мб

64 Кб

Використовується для великих задач

far – 4б

Величезна (huge model)

1 Мб

64 Кб

1 Мб

64 Кб

Використовується для великих задач

far – 4б