Покажчики. Частина 1. Загальні поняття. Типи покажчиків. Керовані та некеровані покажчики. Покажчики на функцію. Приклади використання
Зміст
- 1. Що таке покажчик? Визначення покажчика
- 2. Які типи покажчиків підтримуються в C++?
- 3. Яка відмінність між керованими та некерованими покажчиками?
- 4. Що таке покажчики посилального типу або керовані покажчики (managed pointers)?
- 5. Приклад використання керованих покажчиків. Утиліта gcnew та ключове слово ref в Visual Studio C++
- 6. Що таке некеровані покажчики (unmanaged pointers) та некеровані покажчики на функції (unmanaged function pointers)?
- 7. Яка загальна форма оголошення некерованого покажчика (unmanaged pointer)? Приклад
- 8. Некеровані покажчики. Операція взяття адреси &. Приклад
- 9. Приклад використання некерованого покажчика на функцію
- 10.Приклад використання керованого покажчика на функцію в середовищі C++/CLI (делегати)
- 11. Яка відмінність між покажчиком-змінною та покажчиком-константою?
- Зв’язані теми
Пошук на інших ресурсах:
1. Що таке покажчик? Визначення покажчика.
Однією з переваг мови C++ порівняно з іншими мовами програмування є використання покажчиків для доступу до змінної. Також, як відомо, доступ до змінної можна організувати за її іменем.
З допомогою покажчиків можна зручно організовувати, наприклад, зв’язані списки та динамічне виділення пам’яті.
Покажчик – це змінна, яка містить адресу іншої змінної в пам’яті. Наприклад, якщо змінна a містить адресу змінної b, то це означає, що змінна a вказує на змінну b.
2. Які типи покажчиків підтримуються в C++?
В Visual C++ (CLR – Common Language Runtime) підтримуються три типи покажчиків:
- керовані покажчики (managed pointers);
- некеровані покажчики (unmanaged pointers);
- некеровані покажчики на функції (unmanaged function pointers).
3. Яка відмінність між керованими та некерованими покажчиками?
Відмінність між керованими і некерованими покажчиками полягає в наступному:
на відміну від керованого покажчика некерованому покажчику можна присвоїти будь-яку адресу пам’яті, навіть ту, яка знаходиться за межами виконавчого середовища.
У цьому випадку пам’ять є нерегульована.
У випадку регульованої пам’яті керованому покажчику присвоїти адресу за межами виконавчого середовища не вдасться.
4. Що таке покажчики посилального типу або керовані покажчики (managed pointers)?
Керовані покажчики – це покажчики посилального типу. Ці покажчики передаються для аргументів, методів, які передаються за посиланням. Ці покажчики є сумісні з специфікацією Common Language Runtime (CLR). Керовані покажчики є посиланнями на об’єкти. Ці об’єкти розміщуються в загальній керованій пам’яті, яка виділяється для програми в момент її виконання.
У таких покажчиках замість символу * застосовується символ ^. Для виділення пам’яті під керований покажчик використовується утиліта gcnew.
5. Приклад використання керованих покажчиків. Утиліта gcnew та ключове слово ref в Visual Studio C++
В керованих покажчиках утиліта gcnew формує екземпляр деякого об’єкту. Утиліта gcnew виділяє пам’ять для екземпляра об’єкту і повертає посилання на цей об’єкт.
Опис цього об’єкту повинен починатися з ключового слова ref. Ключове слово ref дає інформацію про те, що опис є посилального типу. Загальна форма використання ключового слова ref має вигляд:
ref опис;
Після такого опису пам’ять під об’єкт виділяється з допомогою утиліти gcnew.
Приклад. У прикладі демонструється:
- опис структури типу BOOK посилального типу, що містить інформацію про книгу;
- використання ключового слова ref для вказання того, що структура є посилального типу;
- використання утиліти gcnew для виділення пам’яті під структуру;
- демонстрація використання керованих покажчиків для оперування об’єктами.
Нехай за межами опису класу описується наступна структура:
ref struct BOOK // ref - означає, що структурає посилального типу { System::String ^ Title; // заголовок книги System::String ^ Author; // прізвище автора книги int year; // рік видання float price; // вартість книги };
Тоді в методах цього класу можна використовувати структуру BOOK приблизно таким чином:
... BOOK ^ B; // змінна B є типу "керований покажчик" B = gcnew BOOK; // виділення пам'яті під структуру // заповнення полів структури B->Title = "Title of Book"; B->Author = "Author of Book"; B->year = 1998; B->price = 399.85f; ...
6. Що таке некеровані покажчики (unmanaged pointers) та некеровані покажчики на функції (unmanaged function pointers)?
Некеровані покажчики – це традиційні покажчики C/C++. Вони є покажчиками на об’єкти в нерегульованому об’ємі пам’яті, що виділяється для виконання програми. Некеровані покажчики не є сумісні зі специфікацією CLR.
Некеровані покажчики на функції – це покажчики на функції, які можна обробляти таким самим чином як і некеровані покажчики на об’єкти (дані).
Особливості використання некерованих покажчиків більш детально описані в наступній темі.
7. Яка загальна форма оголошення некерованого покажчика (unmanaged pointer)? Приклад
Загальна форма оголошення покажчика:
тип_змінної * імя_покажчика;
де
- тип_змінної – це тип тієї змінної, на яку вказує покажчик. Його ще називають базовий тип покажчика;
- імя_покажчика – імя змінної-покажчика.
Приклад. Опис покажчиків, які вказують на різні типи змінних.
int * pi; // покажчик з іменем pi на тип int float * pf; // покажчик з іменем pf на тип float
8. Некеровані покажчики. Операція взяття адреси &. Приклад
Для отримання адреси змінної в пам’яті використовується операція взяття адреси &. Ця операція є унарною. Вона повертає адресу свого операнда в пам’яті.
Приклад операції взяття адреси та використання покажчика для доступу до змінної.
int * pi; // покажчик з іменем pi на тип int float * pf; // покажчик з іменем pf на тип float float f; int i; i = 8; pi = &i; // pi вказує на i *pi = 10; // i = 10 f = 2.93f; pf = &f; // pf вказує на f *pf = 8.85f; // f = 8.85
Рисунок 1 схематично показує використання покажчиків для типу int.
Рисунок 1. Використання покажчика на тип int
Як видно з рисунку 1, з допомогою покажчика можна отримати доступ до змінної та змінити її значення. У цьому випадку тип, на який вказує покажчик, повинен співпадати з типом змінної.
9. Приклад використання некерованого покажчика на функцію.
Покажчики на функцію дозволяють організовувати виклик функцій у вигляді ланцюга в залежності від вимог. У цьому випадку функції, що виконують різну роботу, повинні:
- мати однакову кількість та типи аргументів;
- повертати значення однакового типу.
При оголошенні, покажик на функцію записується наступним чином:
тип (*ім'я_функції) (список_параметрів);
де
тип – тип значення, що повертається функцією.
Приклад. Використання некерованого покажчика на функцію для консольного додатку.
Опис та використання покажчика на функцію з іменем func_ptr, яка отримує два цілочисельних параметри x, y і повертає значення типу double.
Нехай дано 2 функції, які мають однакову кількість параметрів та повертають однакове значення:
// функція, що підносить x в степені y double Power(int x, int y) { double res; res = System::Math::Pow((double)x, (double)y); return res; } // функція, що ділить x на y double Div(int x, int y) { double res; res = (double)x / (double)y; return res; }
У консольному додатку можна використовувати даний покажчик так:
// описати покажчик на функцію, що отримує 2 параметри типу int double (*func_ptr)(int x, int y); double res; ... // виклик функції піднесення до степеня func_ptr = Power; // вказує на Power - піднесення до степеня res = (*func_ptr)(4,3); // res = 64 // виклик функції ділення чисел через покажчик func_ptr = Div; // func_ptr вказує на Div res = (*func_ptr)(4,3); // res = 1.33333333333333
Такий спосіб використання покажчиків на функцію підходить тільки для консольних додатків.
10. Приклад використання керованого покажчика на функцію в середовищі C++/CLI (делегати)
Використання покажчика на функцію в середовищі C++/CLI для додатків, створених за шаблоном Windows Forms. У цьому випадку потрібно використовувати так звані делегати. Делегати підтримуються в .NET Framework.
Нехай дано 2 функції, які мають однакову кількість параметрів та повертають однакове значення:
// функція, що підносить x в степені y public: double Power(int x, int y) { double res; res = System::Math::Pow((double)x, (double)y); return res; } // функція, що ділить x на y public: double Div(int x, int y) { double res; res = (double)x / (double)y; return res; }
Щоб використати делегат потрібно спочатку в деякому місці класу форми (або іншого класу) дати такий опис:
// опис делегату DelFun, що отримує два параметри типу int // і повертає значення типу double public: delegate double DelFun(int , int); ...
Після цього в деякому методі (наприклад, обробнику події кліку на кнопці) можна використовувати цей покажчик наступним чином:
double result; DelFun ^ PFun = gcnew DelFun(this, &Lab1::Form1::Power); result = PFun(3,2); // result = 9 PFun = gcnew DelFun(this, &Lab1::Form1::Div); result = PFun(3,2); // result = 1.5
У вищенаведеному прикладі в рядках
&Lab1::Form1::Power ... &Lab1::Form1::Div
ідентифікатори мають наступне призначення:
- Lab1 – назва проекту;
- Form1 – назва головної форми додатку (ім’я змінної);
- Power – назва функції.
⇑
11. Яка відмінність між покажчиком-змінною та покажчиком-константою?
Покажчик-змінна (покажчик) – це змінна, яка призначена для збереження адреси в пам’яті.
Покажчик-константа – це значення адреси оперативної пам’яті.
Зв’язані теми
- Покажчики. Частина 2. Некеровані покажчики. Операції над покажчиками. Покажчик на тип void. Виділення пам’яті. Нульовий покажчик. Операція взяття адреси &
- Покажчики. Частина 3. Некеровані покажчики і масиви. Покажчик на структуру. Покажчик на клас
- Покажчики. Частина 4. Покажчики і рядки символів. Використання покажчиків при перетворенні і конвертуванні рядків
- Покажчики. Частина 5. Виділення пам’яті для покажчика. Масиви покажчиків на базові типи, функції, структури, класи
- Покажчики. Частина 6. Складені native та managed типи даних. Керовані покажчики (^) в середовищі CLR. Виділення пам’яті. Кваліфікатори ref та value. Керовані покажчики (^) на структури, класи
- Масиви. Частина 1. Визначення масиву. Одновимірні масиви. Ініціалізація масиву
- Масиви. Частина 2. Двовимірні масиви. Масиви рядків. Багатовимірні масиви