Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Lab4.doc
Скачиваний:
9
Добавлен:
21.09.2019
Размер:
146.94 Кб
Скачать

Вказівники і масиви

Масиви і вказівники тісно пов’язані між собою. Розглянемо такий фрагмент:

сhar str[80], *p1; p1 = str;

тут р1 вказує на перший елемент масиву str. Якщо необхідно отримати доступ до п’ятого елемента str, то необхідно записати:

str[4], або *(p1+4)

Обидва оператори повертають п’ятий елемент.

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

Використання масиву

Використання вказівників

int puts(const char *s)

{

register int i;

for(t=0; s[t]; ++t)putchar(s[t]);

return 1;

}

int puts(const char *s)

{

while(*s) putchar(*s++);

return 1;

}

Професійні програмісти віддадуть перевагу версії з вказівниками при написанні програм. Фактично, версія з вказівником демонструє типовий спосіб написання програм на С.

Вказівники на символьні масиви

Багато рядкових операцій в С виконується за допомогою вказівників, оскільки доступ до рядків здійснюється послідовно.

Наприклад, тут показана версія із стандартної бібіліотеки функції strcmp(), в якій використовуються вказівники:

//Використання вказівників

int strcmp(const char *s1, const char *s2)

{

while(*s1)

if(*s1-*s2)

return *s1-*s2;

else {

s1++;

s2++;

}

return 0; //рівність

}

Треба пам’ятати, що всі рядки в С закінчуються нульовим символом, який інтерпретується як false ("неправда"). Тоді оператор

while (*s1)

видає "істину", поки не досягне кінця рядка, strcmp() повертає нуль, якщо s1 = s2. Вона повертає число, менше 0, якщо s1 < s2.

Масиви вказівників

Можна створювати масиви вказівників. Для оголошення масиву цілочисельних вказівників з десяти елементів слід написати

int *x[10];

Для присвоєння адреси цілочисельної змінної Срр третьому елементу масиву слід написати:

x[2] = &Cpp;

для отримання значення цілочисельної змінної Срр слід написати:

*x[2];

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

void display_array(int *q[])

{

int t;

for(t=0; t<10; t++)

printf("%d",*q[t]);

}

Необхідно пам’ятати, що q – це не вказівник на ціле, а масив вказівників на цілі. Отже, q – необхідно оголосити як масив цілих вказівників. Його не можна оголосити як простий цілочисельний вказівник, бо він ним і не є.

Вказівники на вказівники

У випадку вказівників на змінні, вказівник містить адресу деякої ділянки пам’яті, яка містить деяке значення. У випадку вказівника на вказівник, перший вказівник містить адресу другого вказівника, який в свою чергу містить адресу комірки пам’яті, в якій міститься деяке значення.

Загальний синтаксис для оголошення вказівника на вказівник:

type** PointerToPoinetrName;

Приклади оголошення, ініціалізації і використання вказівників на вказівники.

int nNum = 1;

int* pnNum = &nNum;

int ** ppnNum = &pnNum;

cout << nNum << "\n";

// виводить 1, використовуючи змінну nNum

cout << *pnNum << "\n";

/* виводить 1, використовуючи змінну pnNum */

cout << **ppnNum << "\n";

/* виводить 1, використовуючи вказівник на вказівник*/

Обмеження на ініціалізацію вказівника на вказівник: С++ не дозволяє два рази застосовувати оператор звертання за адресою & для присвоєння вказівнику на вказівник адреси вказівника на змінну. Наприклад, такий запис компілятором не сприймається:

int nNum = 1; int **ppnNum = &&nNum;

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]