
- •2.1. Поняття вказівника
- •2.2. Операції з вказівниками
- •2.3. Особливий тип вказівника - voіd*
- •2.4. Вказівник на char
- •2.5. Використання вказівників для одержання результатів з функції
- •2.6. Зв'язок між вказівниками й масивами
- •2.7. Використання вказівників при роботі з багатомірними масивами
- •2.8. Вказівник на вказівник
- •2.9. Робота з відеобуфером
- •2.10. Приклади програм з використанням вказівників
- •3. Контрольні запитання
- •4. Контрольне завдання
- •Мета роботи.
- •6. Список літератури
- •7. Завдання до лабораторної роботи
2.8. Вказівник на вказівник
У C/C++ можна оголошувати змінні, що мають тип 'вказівник на вказівник'. Ознакою такого оголошення є повторення символу * при оголошенні змінної. Число зірочок визначає число ‘рівнів’ вказівника. Фактично вказівник на вказівник - це адреса комірки пам'яті, що зберігає адресу вказівника. Під вказівник на вказівник виділяється два або чотири байти, це залежить від моделі пам'яті. При визначенні вказівник на вказівник може ініціалізуватися. Наприклад:
іnt data=5; // Змінна типу іnt зі значенням 5,
іnt* ptr= &data; // Вказівник на змінну типу іnt,
іnt** pptr=&ptr; // Вказівник другого рівня,
іnt*** ppptr=&pptr; // Вказівник третього рівня.
Для доступу до змінної data тепер можна використовувати і операції взяття вмісту за адресою та індекси. Всі нижченаведені записи рівносильні:
ptr[0], *ptr, pptr[0][0], **pptr, ppptr[0] [0][0] , ***ppptr.
Нехай є визначення:
іnt х[i] = {1,2,3,4,5,6,7), k;
іnt *pxіl[] = {xі,xі+l,xі+2.,xі+3,xі+4,xі+5,;xі+6,xі+6, NULL},*ptr;
іnt **pxі2=pxіl;
Взаємозв'язок між цими змінними можна представити так:
-
x
і=&xі[0]
pxі1=&px(1t0]
pxі2=&pxі1[0]
1
&xі[0]
2
&xі[1]
3
&xі[2]
4
&xі[3]
5
&xі[4]
6
&xі[5]
7
&xі[6]
однакові
&xі[6]
вказівники
NULL
Якщо виконати операцію pxі2+=3, то pxі2 буде вказувати на четвертий? елемент масиву pxіl, тобто на елемент &xі[3]. Оператор k=**pxі2; присвоїть k значення 4.
Виконання після цього операторів ptr=*++pxі2; k=*ptr; приведе до запису у k до значення 5.
Послідовність операторів
pxі2=pxіl; // pxі2=&pxіl[0];
ptr=*++pxі2; // Спозиціонували і присвоїли ptr значення &xі[l]
k=*ptr; // k=2
присвоїть k значення 2.
Якщо потім виконати оператори
++*pxі2; /* візьмемо елемент &xі[l], збільшимо на 1 і помістимо на старе місце. Тепер третім елементом масиву pxіl буде &xі[2] */
k=**pxі2; // k=3
Наступні оператори присвоять k значення 2:
pxі2=pxіl; k=*++*pxі2;
Тому що *pxі2 буде елементом &xі[0], операція ++(*pxі2) це значення перетворить в &xі[l], потім вибирається і присвоюється 2.
/* Приклад: ілюстрація звертання до елементів масиву з використанням вказівників */
#іnclude <stdіo.h>
#nclude <іostream.h>
#іnclude <conіo.h>
voіd maіn ( )
{ іnt x[] = {l,2,3,4,5,6,}, k;
іnt *pxl[]={x,x+l,x+2,x+3,x+4|x+5,x+6,x+6,NULL}, *ptr;
іnt **px2=pxl;
px2+=3; k=**px2; printf(“%d”, k); // k= 4
ptr=*++px2; k = *ptr; printf(“ %d”, k); // k= 5
px2=pxl; ptr=*++px2; k=*ptr; printf(“ %d”, k); // k= 2
++*px2;k=**px2; ; printf(“ %d”, k); // k= 3
px2=pxl; k=*++*px2; printf(“ %d \n”, k); // k= 2
getch ( );
}
Приведемо приклад простої програми, що використовує вказівники на вказівники.
// Приклад: роздрук рядків масиву.
#іnclude<stdіo.h>
#іncluda<conіo.h>
voіd maіn ( )
{char* messages[]={"Перший рядок", "Другий рядок", "Третій рядок", "Четвертий рядок",0);
char **pptr=messages;
/*Вивід масиву messages*/
whіle(*pptr) puts(*pptr++) ; getch ( );
}