Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Шпора II Sem.doc
Скачиваний:
0
Добавлен:
01.04.2025
Размер:
679.94 Кб
Скачать

11.2. Застосування покажчиків на функції

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

Покажчики на функції також дають змогу передавати функції як аргументи іншим функціям. Адресу функції можна отримати, використовуючи ім'я функції без круглих дужок і аргументів2. Якщо присвоїти адресу функції покажчику, то цю функцію можна викликати через покажчик. Щоб зрозуміти сказане, розглянемо наведену нижче програму. Вона містить дві функції – vLine() і hLine(), які малюють на екрані вертикальні та горизонтальні лінії заданої довжини.

Демонстрація механізму застосування покажчиків на функції

#include <vcl>

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

#include <conio> // Для консольного режиму роботи

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

void vLine(int i), hLine(int i);

int main()

{

void (*p)(int i);

p = vLine; // Покажчик на функцію vLine()

(*p)(4); // Виклик функції vLine()

p = hLine; // Покажчик на функцію hLine()

(*p)(5); // Виклик функції hLine()

getch(); return 0;

}

void hLine(int i)

{

for(; i; i--) cout << "-";

cout << endl;

}

void vLine(int i)

{

for(; i; i--) cout << "|" << endl;

}

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

|

|

|

|

–––––

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

У наступному рядку покажчику р присвоюється адреса функції vLine(). Потім здійснюється виклик функції vLine() з аргументом 4. Після цього покажчику р присвоюється адреса функції hLine(), і за допомогою цього покажчика реалізується її виклик. У цьому коді програми під час виклику функцій за допомогою покажчика використовується такий формат:

(*р)(4);

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

р(4);

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

11.2.2. Пошук адреси перевизначеної функції

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

У наведеному нижче прикладі коду програми міститься дві версії функції space(). Перша версія виводить на екран count пропусків, а друга – count символів, переданих як аргумент ch. У функції main() оголошуються два покажчики на функції. Перший заданий як покажчик на функцію з одним цілочисельним параметром, а другий – як покажчик на функцію з двома параметрами.

Демонстрація механізму використання покажчиків на дві перевизначені функції для виведення на екран відповідно пропусків і символів

#include <vcl>

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

#include <conio> // Для консольного режиму роботи

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

// Введення на екран count пропусків.

void space(int count)

{

for(; count; count–-) cout << " ";

}

// Введення на екран count символів, переданих в ch.

void space(int count, char ch)

{

for(; count; count-–) cout << ch;

}

int main()

{

// Створення покажчика на void-функцію з одним int-параметром.

void (*fp1)(int);

/* Створення покажчика на void-функцію з одним int-параметром

і одним параметром типу char. */

void (*fp2)(int, char);

fp1 = space; // Отримуємо адресу функції space(int)

fp2 = space; // Отримуємо адресу функції space(int, char)

fp1(22); // Виводимо 22 пропуски (цей виклик є аналогічним

// виклику (*fp1)(22)).

cout << "|" << endl;

fp2(30, 'x'); // Виводимо 30 символів "x" (цей виклик є

// аналогічним до виклику (*fp2)(30, 'x').

cout << "|" << endl;

getch(); return 0;

}

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

|

хххххххххххххххххххххххххххххх|

Як зазначено у коментарях до цієї програми, компілятор здатний визначити, адресу якої перевизначеної функції він отримує, на основі того, як оголошено покажчики fp1 і fр2.

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

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