Реферат: Массивы 2
printf("%p", р); /* друк вмісту р */
printf("%p",g); /* друк вмісту g */
р г і n t f (" % d % d ", x, * g); / * друк величини хі величини за адресою g*/
} Результат: FFF4 FFF4 10 10
У цьому прикладі приведена ще одна специфікація формату функції printf() - %р. Цей формат використовується для друку адреси пам'яті в шістнадцятковій формі.
Не можна створити змінну типу void, але можна створити покажчик на тип void. Покажчику на void можна привласнити покажчик будь-якого іншого типу. Однак при зворотному привласненні необхідно використати явне перетворення покажчика на void/void *pv;
float f, *pf;
pf=&f;
pv=pf;
pp=(fioat*) pv;
У мові С допустимо привласнити покажчику будь-яку адресу пам'яті. Однак, якщо оголошений покажчик на ціле
int *р;
а за адресою, яка привласнена даному покажчику, знаходиться змінна х типу float, то при компіляції програми буде видане повідомлення про помилку в рядку
р=&х;
Цю помилку можна виправити, перетворювавши покажчик на int до типу покажчика на float явним перетворенням типу:
p=(int*)&x;
Але при цьому втрачається інформація про те, на який тип вказував початковий покажчик.
Як і над іншими типами змінних, над покажчиками можна виробляти арифметичні операції: складання і віднімання (операції ++ і є окремими випадками операцій складання і віднімання). Арифметичні
дії над покажчиками мають свої особливості. Виконаємо найпростішу програму
#include <stdio. h> void main() { і n t x= 1 0;
int *p, *g;
p=&x;
g=p;
printf("%p", p); /* друк вмісту p */ printf("%p", p++); /* друк вмісту g */ } Результат: FFF4 FFF6
Після виконання цієї програми ми побачимо, що при операції ++1 значення покажчика р збільшилося не на 1, а на 2. І це правильне, оскільки нове значення покажчика повинно вказувати не на наступну адресу пам'яті, а на адресу наступного цілого. А ціле, як ми пам'ятаємо, займає 2 байти. Якби базовий тип покажчика був не int, a double, то були б надруковані адреси, відмінні на 8 (Результат:
FFEE FFF6), саме стільки байт пам'яті займає змінна типу double, тобто при кожній операції ++р значення покажчика буде збільшуватися на кількість байт, що займаються змінної базового типу покажчика .
Операції над покажчиками не обмежуються тільки операціями ++ і
--. До покажчиків можна додавати деяке ціле або відняти ціле. int *p=2000; float *p=2000;
Р=Р+3; р=р+10;
Результат: р=2006 Результат: р=2040
Загальна формула для обчислення значення покажчика після виконання операції р=р+п; буде мати вигляд
<р>=<р>+п*<кільк.байтів пам'яті базового типу покажчика>
Можна також відняти один покажчик з іншого. Так, якщо р і pi -покажчики на елементи одного і того ж масиву, то операція р-рі дає такий же результат, як і віднімання індексів відповідних елементів масиву.
Інші арифметичні операції над покажчиками заборонені, наприклад не можна скласти два покажчики, помножити покажчик на число і т.д.
#include <std io. h > void rnai n() { int *p, *g, x; p=&x; g=p; printf("\n\n\np=%p", p); P= P + 8; printf(" p+5=%p", p); printf(" g=%p", g); printf(" p-g=%p", p-g); } Результат: p=07DO p+5=07EO g=07DO p-g=0008 | #incl ude <std io. h> void main() { int *p, *g, x; p=&x; g=p; p r і n t f (" \ n \ n \ n p = % p ", p); P= P + 8; printf(" p+5=%p", p); printf(" g=%p", g); printf(" p+g=%p", p+g); } Результат: Error UKAZAT2.CPP 14: Invalid pointer addition |
Покажчики можна порівнювати. Застосовні всі 6 операцій:
<, >, <=, >=, =, == і !=.
Порівняння р < g означає, що адреса, що знаходиться в р, менше адреси, що знаходиться в g.
Якщо рід вказують на елементи одного масиву, то індекс елемента, на який вказує р, менше індексу масиву, на який вказує g.
ЗВ'ЯЗОК ПОКАЖЧИКІВ І МАСИВІВ
Будь-який доступ до елемента масиву за допомогою операції індексування може бути виконаний за допомогою покажчика (що в загальному випадку працює швидше).
Декларація
int a[10]
визначає масив а розміру 10:
Запис а[і] посилає нас до і-му елемента масиву. int *р;
р=&а[0]; /* р вказує на нульовий елемент а або містить адресу елемента а[0] */
х = *р; => х = а[0], У= *(Р+1); => У = а[1];