Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Архив WinRAR / 2_Посібник_С_002.doc
Скачиваний:
39
Добавлен:
17.05.2015
Размер:
2.7 Mб
Скачать

5.3 Масиви

А тепер повернемося до масивів. Нехай є опис int a [5]; Він визначає масив розміром 5 елементів, тобто п'ять послідовних розташованих осередків пам'яті a [0], a [1], a [2], a [3], a [4]. Адреса i-го елемента масиву дорівнює сумі адреси початкового елемента масиву і зміщення цього елемента на i одиниць від початку масиву. Це досягається індексуванням: a [i] - i-й елемент масиву. Але доступ до будь-якого елементу масиву може бути виконаний і за допомогою покажчиків, причому, більш ефективно. Якщо uk-покажчик на ціле, описаний як int * uk, то uk після виконання операції uk = &a[0] -містить адресу a [0], а uk + i вказує на i-й елемент масиву. Таким чином, uk + i є адреса a [i]. Оскільки ім'я масиву в програмі ототожнюється з адресою його першого елемента, то вираз uk = & a [0] еквівалентно такому: uk = a. Тому значення a [i] можна записати як *(a+i). Застосувавши до цих двох елементів операцію взяття адреси, отримаємо, що &a[i] та a+i ідентичні.

На прикладі наведено текст програми з функцією obmen (x, y), яка міняє місцями значення двох цілих величин(рис. 5.8). Так як x, y - адреси змінних a і b, то * x і * y забезпечують непрямий доступ значенням a і b. До сказаного додамо, що використання покажчиків дозволяє нам оминати обмеження мови Сі, згідно з якими функцій може повертати лише одне значення.

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

Приклад 7.Заміна місцями значення двох цілих величин.

/ * обмін a і b * /

#include <stdio.h>

void zamina (int * x, int * y){

int t;

t =* x;

* x =* y;

* y = t;

}

int main () {

int a, b;

a = 3; b = 7;

zamina (&a, & b);

printf ("a =% d b =% d", a, b);

}

Рисунок 5.8 - Заміна місцями значення двох цілих величин.

На схемі вказано як відбувається обмін між aіb. Суцільними лініями вказано я ми через код бачимо обмін, пунктиром, як відбувається обмін самих даних.

У визначенні функції формальні параметри char s [] і char * s абсолютно ідентичні.

5.4 Операція s++

(приклад 2) збільшення на одиницю поточне значення покажчика, спочатку вказує на перший символ рядка, а операція * s! = '\ 0' порівнює черговий символ ознакою кінця рядка.

Приклад 8Збільшення на одиницю поточне значення покажчика

/ * довжина рядка * /

int length (char * s) {

int i;

for (i = 0; * s! = '\ 0'; s++)

i++;

return i;}

5.5 Операції ==, !=

Крім раніше розглянутих операцій адресної арифметики, до покажчиків можна застосувати операції порівняння == і! =. Навіть операції відношення <,> = і т.п. працюють правильно, якщо покажчики посилаються на елементи одного і того ж масиву. В останньому випадку можливе навіть віднімання посилань: якщо u і s посилаються на елементи одного масиву, то us є число елементів між u і s. Використовуємо цей факт для складання ще однієї версії функції length (рис. 5.9). Спочатку u вказує на перший символ рядка (char * u = s). Потім у циклі по черзі перевіряється кожен символ, поки зрештою не буде виявлений "\ 0". Різниця us дає саме довжину рядка.

Приклад 9. Функція length

/ * довжина рядка * /

int length (char * s) {

char * u = s;

while (* u! = '\ 0')

u++;

return (u-s);

}

Рисунок 5.9 – Ілюстрація функції length

І для даного випадку u-s = 3(останній нуль-символ не рахується).

Соседние файлы в папке Архив WinRAR