- •Покажчик – це змінна для адреси елементу пам'яті. Загальний формат оголошення покажчика має
- •Програма 1. Оголошує покажчик. Видає випадкову інформацію з області пам'яті, яка виділяється під
- •Перша область відводиться під покажчик. Ця область пам'яті має ім'я р. Друга область
- •Програма 2. Оголошує покажчик. Видає інформацію з областей пам'яті p і *p, які
- •Покажчику можна привласнити адресу однотипної змінної, яка оголошена в програмі. Наприклад, після виконання
- •У покажчик можна вводити інформацію з клавіатури, використовуючи директиву введення формату scanf() із
- •Схема пам'яті після оголошення змінних дана на мал. 2.
- •Програма 4. Оголошує покажчик. Для ініціалізації покажчика використовується директива new.
- •Розберемо роботу програми. Схема пам'яті після оголошення змінних дана на мал. 4.
- •Програма 5. Оголошує покажчик. Адреса в покажчик вводиться з клавіатури директивою scanf, в
- •Дана програма спочатку видасть адресу змінної x у форматі процесора. Потім в цьому
- •Покажчик на покажчик – це змінна для адреси покажчика.
- •Тут AY, A, N – випадкові числа у відповідних областях пам'яті. Області з
- •Програма 6. Оголошує покажчик на покажчик. Видає інформацію з областей пам'яті, які
- •Відмітимо, що якщо змінна p визначається, наприклад, кодом int **p, то при виконанні
- •Дана програма показує, що значення в змінній а і адреса першого елементу масиву
- •Програма 8. Програма демонструє способи доступу до елементів масиву через адреси, обчислює суму
- •Якщо задана матриця, наприклад а[n][m], то для неї визначений масив покажчиків а[n]. У
- •Програма 9. Демонструє, що при оголошенні двовимірного масиву, визначений масив покажчиків на перші
- •void main(void)
- •fclose(f1);
- •Під динамічною пам'яттю розуміється пам'ять, яка виділяється під час роботи програми. У мові
- •пам'яті під одновимірний масив.
- •Програма 12. Програма демонструє той факт, що при оголошенні покажчика в програмі можна
- •Програма 13. Для виділення динамічній пам'яті під матрицю
- •Програма 14. Виділяється динамічна пам'ять під матрицю з використанням масиву покажчиків.
Розберемо роботу програми. Схема пам'яті після оголошення змінних дана на мал. 4.
Після виконання коду p = new int комп'ютер виділяє пам'ять з адресою AN і адреса даної пам'яті заноситься в покажчик р. Стан пам'яті в цьому випадку на мал. 5
Програма 5. Оголошує покажчик. Адреса в покажчик вводиться з клавіатури директивою scanf, в якій використовується специфікація
%p.
void main()
{ |
|
int *p; |
// Змінна p для запису адрес комірок. |
int x = 2; clrscr();
cout << " Стан пам'яті до ініціалізації!!!: \n\n"; cout << "В неконтрольованій адресі " << p << " міститься випадкове число " << *p << "\n\n";
printf("Адреса змінної x у форматі \n який визначений " "процесором = %p",&x);
cout << "\n\n Введи адресу змінної x у форматі \n"
<< " який визначений процесором (див. попередній вивід) "; scanf("%p",&p);
cout<<"\n\n Стан пам'яті після ініціалізації покажчика: \n\n"; printf("У змінній p адреса %p. У цій адресі число %d\n",p,*p); getch(); }
Дана програма спочатку видасть адресу змінної x у форматі процесора. Потім в цьому ж форматі з клавіатури в покажчик p вводиться адреса змінної x. Далі після введення в p адреси x виводимо вміст змінної p (там має бути адреса x) і *p (тобто вміст x = 2).
Покажчик на покажчик – це змінна для адреси покажчика.
Загальний формат оголошення покажчика на покажчик має вигляд
<тип> **<имя>
Наприклад, коди (директиви) int **p; float **r; виділяють дві області пам'яті p і r розміром два байти. При цьому змінна p призначена для запису адрес покажчиків типа int, а змінна r призначена для адрес покажчиків типа float. З визначення покажчика на покажчик витікає, що якщо оголошені змінні p і а як змінні типа int **p і int *a, то справедливий код p = &a. На схемі мал. 6 представлений стан пам'яті після виконання коди int **p.
Тут AY, A, N – випадкові числа у відповідних областях пам'яті. Області з адресами AY і A або, що одне і те ж, з іменами *p і **p доступні, але не під контролем програми. Тому використання цих областей пам'яті при роботі програми є помилкою. Справедлива тотожність AY = &*p і A = &**p
Програма 6. Оголошує покажчик на покажчик. Видає інформацію з областей пам'яті, які
доступні програмі. |
|
void main() |
|
{ int **p; |
// Оголошується змінна p для запису адрес покажчиків. |
//При такому визначенні доступні три області пам'яті:
//p – для адреси покажчика;
//*p – для адреси цілого числа;
//**p – для цілого числа.
clrscr();
cout << " Три області пам'яті, які доступні програмі: \n\n";
// Видає адресу покажчика, який міститься в змінному р. printf ("У p міститься не контрольована програмою адреса:" "\n %p – шістнадцятиричний запис адреси у форматі \n" "який визначає процесор. \n\n",p);
//Видає адресу змінної цілого типа
//який міститься в змінній *p.
printf("У *p міститься не контрольована програмою адреса:" "\n %p – шістнадцятиричний запис адреси у форматі \n"
" який визначає процесор. \n\n",*p); // Видається число із змінної з ім'ям **p.
printf("У **p міститься не контрольоване програмою "
"\n число: %d\n", **p); |
|
cout << "\n |
Адреси даних областей памяти:\n\n"; |
printf("Адреса p = %p\n", &p); printf("Адреса *p = %p\n", &*p); printf("Адреса **p = %p\n", &**p); getch(); }
Відмітимо, що якщо змінна p визначається, наприклад, кодом int **p, то при виконанні коду p = new *int виділяється пам'ять під покажчик і адресу цієї області пам'яті заноситься в р.
На закінчення перерахуємо всі операції над покажчиками, які допустимі в мові С/С++:
привласнення для однотипних покажчиків;збільшення (віднімання) значення вираження цілого типа;унарні операції ++, --;порівняння для однотипних покажчиків;
різниця між однотипними покажчиками. Результатом різниці є число цілого типа.
У мові С/С++ ім'я масиву є покажчиком на перший елемент. Це означає, що якщо, наприклад, визначений масив int x[n], то в змінній x міститься адреса першого елементу масиву. Значення змінної x в цьому випадку можна привласнювати покажчику того ж типа.
Програма 7. Демонструє факт, що ім'я масиву є покажчиком на перший елемент.
void main(void)
{
const n = 10;
int а, i; // Ім'я масиву а є покажчиком на елемент а[0]. clrscr();
cout << "В змінній а знаходиться адреса " << а << "\n"; cout << "Адреса 1-го елементу масиву " << &a[0] << "\n"; getch(); }
Після виконання цієї програми на екрані видачі результатів з'явиться наступне повідомлення:
У змінній а знаходиться адреса 0xN
Адреса 1-го елементу масиву |
0xN |
Дана програма показує, що значення в змінній а і адреса першого елементу масиву (&а[0]) збігаються за значенням і типом. Такий зв'язок масиву з покажчиком дозволяє організувати доступ до елементів масиву через їх адреси. А саме:
якщо i – поточний індекс масиву a[], то його адреса відповідає коду a+ i, тобто справедлива тотожність &a[i] = а + i і
*(а + i) = а[i];
якщо в деякому покажчику p, тип якого відповідає типові масиву a[], міститься адреса елементу цього масиву, то індекс цього елементу обчислюється за формулою i = p – а. Справедлива тотожність *p = а[i].