Вказівники-константи і вказівники-змінні 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Вказівники-константи і вказівники-змінні



Припустімо, що ми хочемо використати операцію збільшення замість додавання j до імені intarray. Чи можна записати вираз *(intarray++)?

Так зробити не можна, оскільки не можна міняти константу. Вираз intarray є адресою в пам’яті, де наш масив зберігатиметься до кінця роботи програми, тому intarray – вказівник константи. Ми не можемо записати intarray++, так само як не можемо записати 7++. Натомість можна збільшити вказівник, який містить цю адресу. В програмі 12.7 показано, як це можна зробити:

 #include<iostream.h>

 #include<conio.h>

 #include<stdio.h>

 #include<bios.h>

 int main()

 {clrscr();

int intarray[5]={31,54,77,52,93};

int* ptrint;

ptrint=intarray;

for(int j=0;j<5;j++)

cout<<*(ptrint++)<<endl;

 bioskey(0);

 return 0;

 }

Програма 12.7

Тут ми визначили вказівник на int – ptrint – і потім присвоїли йому значення адреси масиву intarray. Тепер ми можемо дістати доступ до елементів масиву, використовуючи вираз:

*(ptrint++)

 

Вказівники і функції

Передача аргументів функції може бути здійснена трьома шляхами: за значенням, за посиланням і за вказівником. Якщо функція призначена для зміни аргументу у викликуваній програмі, то ця змінна не може бути передана за значенням, оскільки функція дістає лише копію змінної. Однак в цій ситуації ми можемо передати змінну за посиланням і за вказівником.

 

Передача простої змінної

В програмі 12.8 показано, як змінна передається за посиланням, в програмі 12.9 (яка виконує такі самі дії, тобто перетворює дюйми на сантиметри) – за вказівником.

 #include<iostream.h>

 #include<conio.h>

 #include<stdio.h>

 #include<bios.h>

 int main()

 {void centimize(double&);//прототип

 clrscr();

 double var=10.0;

 cout<<"var="<<var<<" дюйми"<<endl;

 

 centimize(var);

cout<<"var="<<var<<" см"<<endl;

 

bioskey(0);

 return 0;

 }

 ///////////

 void centimize(double& v)

 {v*=2.54;}

 

Знак &, що записаний після типу double в прототипі функції, означає, що аргумент передається за посиланням.

 

 #include<iostream.h>

 #include<conio.h>

 #include<stdio.h>

 #include<bios.h>

 int main()

 {void centimize(double*);//прототип

 clrscr();

 double var=10.0;

 cout<<"var="<<var<<" дюйми"<<endl;

 

 centimize(&var);

cout<<"var="<<var<<" сантиметри”<<endl;

 

bioskey(0);

 return 0;

 }

 ///////////

 void centimize(double* ptrd)

 {*ptrd*=2.54;}

 

Програма 12.9

Передача вказівника в функцію в якості аргументу в деяких випадках схожа на передачу за посиланням. Вони обидві дозволяють змінній викликаючої програми бути зміненими в функції. Однак механізми їх різні. Посилання – це псевдонім змінної, а вказівник – її адреса.

 

Передача масиву

При передачі масиву в функцію прийнято використовувати вказівники. Розглянемо це на прикладі програми 12.10.

 #include<iostream.h>

 #include<conio.h>

 #include<stdio.h>

 #include<bios.h>

 const int MAX=5;

 int main()

 {clrscr();

  void centimize(double*);//прототип

 double varray[MAX]={10.0,15.1,12.3,13.7,10.2};

 centimize(varray);

 for(int j=0;j<MAX;j++)

 cout<<”varray[“<<j<<”]=”<<varray[j]<<”см”<<endl;

 bioskey(0);

 return 0;

 }

 ////////

 void centimize(double* ptrd)

 {for(int j=0;j<MAX;j++)

 *ptrd++*=2.54;

 }

Програма 12.10

Прототип функції такий сам, як і в попередній програмі; функція має один аргумент – вказівник на double. При передачі масиву за значенням це виглядало б так:

void centimize(double[]);

Записи double* і double[] еквівалентні, але синтаксис вказівника використовується частіше. Оскільки ім’я масиву є його адресою, то ми не маємо потреби використовувати операцію взяття адреси & при виклику функції

centimize(varray);

У функції centimize ми використовуємо досить складний вираз

*ptrd++*

Як дізнатися, що в цьому виразі збільшується вказівник, а не його вміст? Іншими словами: як компілятор проінтерпретує цей вираз - як *(ptrd++), як нам і потрібно, чи як (*ptrd)++? Знаки *(операція розіменування) та ++ мають одинаковий пріоритет. Однак операції однакового пріоритету відрізняються ще й іншим способом – асоціативністю. Асоціативність визначає, як компілятор починає виконувати операції – справа чи зліва. В групі операцій, що мають праву асоціативність, компілятор спершу виконає операцію, яка стоїть справа. Унарні операції * та ++ мають праву асоціативність, тому наш вираз інтерпретується як *(ptrd++) і збільшує вказівник, а не те, на що він вказує. Таким чином, спершу збільшується вказівник, а потім до результату застосовується операція розіменування.

 

Вказівники на рядки

Рядки – це масиви елементів типу char. Таким чином, доступ через вказівники може бути застосований до рядків так само, як і до елементів масиву.

 



Поделиться:


Последнее изменение этой страницы: 2021-12-15; просмотров: 52; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 18.118.100.48 (0.009 с.)