Інформатика
Покажчики : Основні операції над покажчиками
 

Основні операції над покажчиками

     Мова С++ надає можливість використання адрес змінних програми за допомогою основних операцій - & та *:
     За допомогою основних операцій можна отримати значення адреси змінної а використовуючи непряму адресацію - одержати значення змінної за її адресою.
     Призначення цих операцій:
- & ім'я змінної - одержання адреси; визначає адресу розміщення значення змінної визначеного типу;
- * ім'я-покажчика - отримання значення визначеного типу за вказаною адресою; визначає вміст змінної, розміщеної за адресою, що міститься у даному покажчику; це - непряма адресація (інші назви - "зняття значення за покажчиком" або "розіменування" ).
     Оператор присвоювання значення адреси покажчику має вигляд:
iм'я_змінної_покажчика = & ім'я змінної.

Наприклад,
int i, *pi;      // pi -змінна покажчик
pi = &i;           // pi одержує значення адреси 'i'.
     Операція "&" - визначення адреси змінної повертає адресу свого операнда. Операндом операції "&" повинне бути ім'я змінної того ж типу, для якого визначений покажчик лівої частини оператора присвоювання, що одержує значення цієї адреси. У вищенаведеному прикладі це тип int.
     Операції "*" і "&" можна писати впритул до імені операнду або через пробіл. Наприклад: &і, * pi.
     Непряма адресація змінної за допомогою операції "*" здійснює доступ до змінної за покажчиком, тобто повернення значення змінної, розташованої за адресою, що міститься у покажчику. Операнд операції "*" обов'язково повинен бути типу покажчик. Результат операції "*" - це значення, на яке вказує (адресує, посилається) операнд. Тип результату - це тип, визначений при оголошенні покажчика.
     У загальному вигляді оператор присвоювання, що використовує ім'я покажчика та операцію непрямої адресації, можна представити у вигляді:


ім'я змінної =* ім'я-покажчика;

де ім'я-покажчика - це змінна або константа, що містить адресу розміщення значення, необхідного для змінної лівої частини оператора присвоювання.
Наприклад,
i= *pi; // 'i' одержує значення, розташоване за адресою, що міститься в покажчику 'pi'
     Як і будь-які змінні, змінна pi типу покажчик має адресу і значення. Операція & над змінною типу покажчик: &pi - дає адресу місця розташування самого покажчика, pi - ім'я покажчика визначає його значення, a *pi - значення змінної, що адресує покажчик.

Приклад 1. Приклади застосування покажчиків.

#include <iosteam.h>
void main()
{
     char c = 'A';
     int i = 7776;
     int *pi = &i;
     char *pc = &c;
     cout<< "\npi="<<pi<<", *pi="<<*pi<<", &pi="<< &pi;
     cout<<"\npc="<<pc<<", *pc="<<*pc<<", &pc="<< &pc;
}
У результаті виконання буде виведено:
pi = 65522, *pi = 7776, &pi = 65520
pc = 65525, *рс = А, &pc = 65518


Приклад 2. Приклади застосування покажчиків.

#include < iostream.h >

int main ( )

{

     int x = 10;

     int *px = &x;cout << " x =" << x << endl;

     cout << "*px =" << *px << endl;

     x* = 2;                 // або x = x*2;

     cout << " Нове значення* px =" << *px << endl;

     *px += 2;               // або *px =*px + 2;

     cout << " Нове значення* px=, тобто х=" << x << endl;

     return 0;

}

Результат виконання програми:

x = 10

*px = 10

Нове значення *px = 20

Нове значення*px, тобто x = 22

     Одне з основних співвідношень при роботі з покажчиками - це симетричність операцій адресації та непрямої адресації. Вона полягає в тому, що:
*&х == х,

тобто зміст за адресою змінної х є значення х. Наприклад, оголошення покажчика pi і змінних i та j:
int *pi, i = 123, j;
pi = &i; //-присвоювання покажчику значення адреси i
j = *pi; // - присвоювання j вмісту за адресою pi

Тут змінна j отримує pміст, розташований за адресою змінної i, тобто значення змінної, що адресує покажчик pi: j = * pi = * &i = i;. Два останніх вищенаведених оператора виконують те саме, що один оператор: j = i.

     Для повного остаточного розуміння процесів, що відбувається у пам'яті при маніпуляції з покажчиками, розглянемо ще такий фрагмент:

void func()
{
     int х;
     int *pх; // pх - покажчик на змінну типу int
     pх= &х ; // адреса змінної х заноситься в рх
     *pх=77; // число зберігається за адресою, на яку вказує рх
}

     Розглянемо цей приклад на конкретному малюнку: функція займає область пам'яті, починаючи з адреси 0х100, х знаходиться за адресою 0х102, а рх - 0х106. Тоді перша операція присвоювання, коли значення &х(0х102) зберігається в рх, матиме вигляд,

зображений на малюнку 1.

:

Рисунок 1 - Розподіл пам'яті

     Наступну операцію, коли число 77 записується за адресою, яка знаходиться в рх та дорівнює 0х102 (адреса х), відображає наступний малюнок. Запис *рх надає доступ до вмісту комірки, на яку вказує рх.

Рисунок 2 - Розподіл пам'яті, якщо задано значення

Приклад 3. Програма виводу значень покажчика і змісту, розташованого за адресою, що він зберігає.

#include<iostream.h>
void main()
{
     int i = 123, *pi = &i; // pi-покажчик на значення типу int
     cout<<"\n розмір покажчика pi = "<< sizeof(pi);
     cout<<"\n адреса розміщення покажчика pi="<< &pi ;
     cout<<"\n адреса змінної i = "<< &i ;
     cout<<"\n значення покажчика pi = "<< pi ;
     cout<<"\n значення за адресою pi = "<< *pi ;
     cout<<"\n значення змінної i = "<<i ;
}
Результати виконання програми:
розмір покажчика pi = 4
адреса розміщення покажчика pi = 1245060
адреса змінної i=1245060
значення покажчика pi = 1245060
значення за адресою pi = 123

значення змінної i = 123

 
© 2008 ХНУРЭ, Інформатики, Сінельнікова Т.Ф., informatika@kture.Kharkov.ua
Розроблено за допомогою LERSUS