Програмування С, С++теорія та практика (частина 1)
1.8.5 Операції над покажчиками
Мова Сі надає можливості для виконання над покажчиками операцій присвоювання, цілочисельної арифметики та порівнянь. Мовою Сі можливо:
1. присвоїти покажчику значення адреси даних, або нуль;
2. збільшити (зменшити) значення покажчика;
3. додати або відняти від значення покажчика ціле число;
4. скласти або відняти значення одного покажчика від іншого;
5. порівняти два покажчики за допомогою операцій відношення. Змінній-покажчику можна надати певне значення за допомогою
одного із способів:
1. присвоїти покажчику адресу змінної, що має місце в ОП, або нуль, наприклад:
рі = &о; рі = ОТІ^;
2. оголосити покажчик поза функцією (у тому числі поза таіп()) або у будь-якій функції, додавши до нього його інструкцію ь'Шіс; при цьому початковим значенням покажчика є нульова адреса (гаьь);
3. присвоїти покажчику значення іншого покажчика, що до цього моменту вже має визначене значення; наприклад: рі = рі; це - подвійна вказівка однієї і тієї ж змінної;
4. присвоїти змінній-покажчику значення за допомогою функцій саІІос() або таІІос() - функцій динамічного виділення ОП.
Усі названі дії над покажчиками будуть наведені у прикладах програм даного розділу. Розглянемо кілька простих прикладів дій над покажчиками.
Зміну значень покажчика можна робити за допомогою операцій: +, ++, -, —. Бінарні операції (+ та -) можна виконувати над покажчиками, якщо обидва покажчики посилаються на змінні одного типу, тому що об‘єм ОП для різних типів даних може вирізнятися.
Наприклад, значення типу іпі займає 2 байти, а типу/Іоаі - 4 байти. Додавання одиниці до покажчика додасть „квант пам'яті”, тобто кількість байтів, що займає одне значення типу, що адресується. Для покажчика на елементи масиву це означає, що здійснюється перехід до адреси наступного елемента масиву, а не до наступного байта. Тобто значення покажчика при переході від елемента до елемента масиву цілих значень буде збільшуватися на 2, а типу /Іоаі - на 4 байти. Результат обчислення покажчиків визначений у мові Сі як значення типу іпі.
Приклад програми зміни значення покажчика на 1 квант пам'яті за допомогою операції „++”і визначення результату обчислення покажчиків даний на такому прикладі:
#іпс1ийе<з^Ліо.Ь>
Vоій. таіп ()
{
іп£ а[] = { 100, 200, 300 }; іп£ *р-Ьг1, *р£г2 ;
р^г1=а; /*- р'ЬгІ одержує значення адреси а[0] */
р£г2 = &а[2]; /*- р£г2 одержує значення адреси а[2] */ р'Ьг1++; /* збільшення значення р'ЬгІ на квант ОП: р^г1 = &а[1]*/ р£г2++; /* збільшення значення р£г2 на квант ОП: р£г2 = &а[3]*/ ргіп^£ (" р£г2 - р^г1 = %гі\п", р£г2 - р^г1);
}
Результат виконання програми: р£г2 - р£г1 = 2
Результат 2 виконання операції віднімання визначає 2 кванти ОП для значень типу іпі:
р£г2 - р^г1 = &а[3] - &а[1] = (а + 3) - (а + 1) = 2;
У наступному Сі-фрагменті продемонстрований приклад програми для виведення значень номерів (індексів) елементів масивів, адрес першого байта ОП для їх розміщення та значень елементів масивів. Справа в тому, що в Сі є дуже важлива властивість - ім'я масиву еквівалентно адресу його нульового елемента: х == &х[0]. Покажчики рі і р/ спочатку містять значення адрес нульових елементів масивів, а при виведенні складаються з і-номером елемента масиву, визначаючи адресу і-елемента масиву. Для одержання адрес елементів масивів у програмі використовується додавання покажчиків-констант х та у, та змінних-покажчиків рі і р/ з цілим значенням змінної і. Зміна адрес у програмі дорівнює кванту ОП для даних відповідного типу: для цілих
- 2 байти, для дійсних - 4 байти.
#іпс1ийе<з^Ліо.Ь>
Vоій. таіп ()
{
іп£ х[4], *рі = х, і;
£1оа£ у[4], *р£ = у;
ргіп^£("\пномер елемента адреси елементів масивів:\п" "і рі+і х + і &х[і] р£+і у+і &у[і]\п");
£ог (і = 0; і < 4; і++ )
ргіп^£(" %й : %6и %6и %6и %6и %6и %6и\п",
і, рі + і, х + і, &х[і], р£ + і, у + і, &у[і]);
}
Результати виконання програми:
|
номер елемента адреси елементів масивів:
|
Мовою Сі можна визначити адреси нульового елемента масиву х як х або &х[0]: х == &х[0]. Краще і стисло використовувати просто х - це базова адреса масиву. Ту саму адресу елемента масиву можна представити у вигляді: х + 2 == &х[2]; х + і == &х[і].
Те саме значення можна представити у вигляді:
*(х + 0) == *х == х[0] -
значення нульового елемента масиву х; *(х + 2) == х[2] - значення другого елемента масиву х; *(х + і) == х[і] - значення і-го елемента масиву х.
А операції над елементами масиву х можна представити у вигляді: *х + 2== х[0] +2; *(х + і) - 3 == х[і] - 3;
12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
