русс | укр

Мови програмуванняВідео уроки php mysqlПаскальСіАсемблерJavaMatlabPhpHtmlJavaScriptCSSC#DelphiТурбо Пролог

Компьютерные сетиСистемное программное обеспечениеИнформационные технологииПрограммирование


Linux Unix Алгоритмічні мови Архітектура мікроконтролерів Введення в розробку розподілених інформаційних систем Дискретна математика Інформаційне обслуговування користувачів Інформація та моделювання в управлінні виробництвом Комп'ютерна графіка Лекції


Покажчики й аргументи функцій


Дата додавання: 2014-11-28; переглядів: 1019.


Оскільки C передає тільки значення аргументам функцій, не існує прямого способу для викликаної функції змінити значення змінної викликаючої. Для прикладу, певна функція сортування може обмінюватися двома невпорядкованими аргументами з функцією під назвоюswap. Недостатньо написати

swap(a, b);

там де функцію swap визначено як

void swap(int x, int y) /* НЕПРАВИЛЬНО */

{

int temp;

 

temp = x;

x = y;

y = temp;

}

Отримуючи тільки значення, swap не може вплинути на самі змінні а i b у функції, яка викликала swap. Рутина, наведена вище, міняє місцями тільки копії a та b.

Щоб досягти бажаного ефекту, потрібно, щоб викликова програма передала покажчики на значення, які потрібно поміняти:

swap(&a, &b);

Оскільки оператор & добуває адресу змінної, &a буде покажчиком на a. А в самій функції swap, параметри нобхідно оголосити як покажчики, і через їхнє посередництво дістатися самих операндів.

void swap(int *px, int *py) /* міняє місцями *px і *py */

{

int temp;

 

temp = *px;

*px = *py;

*py = temp;

}

Графічно:

викликова

функція

+-----------+

| +---+ |

| a:| |<--|------------------.

| +---+ | |

| b:| |<--|------------------|---.

| +---+ | функція | |

+-----------+ swap | |

+-----------+ | |

| +---+ | | |

|px:| *-|---|---' |

| +---+ | |

|py:| *-|---|-------'

| +---+ |

+-----------+

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

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

Наступний цикл заповнює масив цілими викликаючи getint:

int n, array[SIZE], getint(int *);

 

for (n = 0; n < SIZE && getint(&array[n]) != EOF; n++)

;

Кожний виклик присвоює array[n] значення наступного цілого, знайденого у вводі, і нарощуєn. Зверніть увагу, що суттєвво вказати саме адресу array[n] функції getint, інакше getintне має способу передати перетворене ціле назад викликовій функції.

Наша версія getint повертає EOF у випадку кінця файла, нуль — якщо наступний знак вводу не є цілим, і додатнє значення — якщо ввід містить чинне ціле число.

#include <ctype.h>

 

int getch(void);

void ungetch(int);

 

/* getint: зберігає наступне введене ціле у *pn */

int getint(int *pn)

{

int c, sign;

 

while (isspace(c = getch())) /* опустити пробіли */

;

if (!isdigit(c) && c != EOF && c != '+' && c != '-') {

ungetch(c); /* c не є числом */

return 0;

}

sign = (c == '-') ? -1 : 1;

if (c == '+' || c == '-')

c = getch();

for (*pn = 0; isdigit(c), c = getch())

*pn = 10 * *pn + (c - '0');

*pn *= sign;

if (c != EOF)

ungetch(c);

return c;

}

Скрізь у getint, *pn використовується як звичайна змінна типу int. Ми також використалиgetch і ungetch (описані у Розділі 4.3), тож один зайвий знак, який ми змушені були прочитати, можна було відкинути назад на ввід.

Вправа 5-1. Так як ми написали, функція getint сприймає + або - без числа як чинне числове значення. Виправте цю помилку, щоб таку послідовність було відкинуто.

Вправа 5-2. Напишіть getfloat, аналогічну getint функцію але для чисел з рухомою точкою. Який тип повертає getfloat?


<== попередня лекція | наступна лекція ==>
Покажчики й адреси | Покажчики та масиви


Онлайн система числення Калькулятор онлайн звичайний Науковий калькулятор онлайн