Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Бичков - Основи сучасного програмування.doc
Скачиваний:
69
Добавлен:
07.03.2016
Размер:
2.67 Mб
Скачать

Void swap(int a,int b)

{

int temp=a;

a=b;

b=temp;

}

main()

{

int x=3,y=6;

swap(x,y);

printf("x=%d,y=%d',x,y);

}

Результат роботи: x=3, y=6. Обмін не відбувся. Дійсно, у функції swap утворилися локальні копії фактичних параметрів-змінних x та y, вони помінялись місцями в тілі функції, а у функції main усе залишилось без змін. Для досягнення необхідного нам результату треба передати у функцію swap адреси відповідних змінних і здійснити обмін з їх використанням:

Void swap(int a,int*b)

{

int temp=*a;

*a=*b;

*b=temp;

}

main()

{

int x=3,y=6;

swap(&x,&y);

printf("x=%d,y=%d',x,y);

}

Масиви передаються у функції через адресу першого елемента, тому записи формального параметра у вигляді char*s, char s[10] та char s[ ] еквівалентні.

Компілятор виконує неявні перетворення типів формальних параметрів. Не може бути формального параметра типу, меншого ніж int, серед цілих типів, і ніж double – серед плаваючих.

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

6.3. Функції зі змінною кількістю параметрів

У мові С допускається сигнатура функції вигляду

(<тип1>ident1,<тип2>ident2,...)

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

float (int a,int b,...)

{ …

}

...

a=f(1,2,4,4); /*вірно*/

a=f(1,2); /*вірно*/

a=f(2) /*невірно*/

Допускається також сигнатура вигляду

<СПКП><тип><опусивач>(...).

При цьому функція може мати довільну кількість параметрів, аж до їх відсутності.

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

float (int a,int b,...)

{ …

int *p=…;

}

Тоді *p буде значенням відповідного параметра. Далі доступ здійснюється шляхом збільшення покажчика на 1:

p++

та використання операцій явного зведення типу.

Аналогічно можна було б ініціалізувати покажчик p адресою останнього визначеного елемента

p=&b

і, збільшуючи його значення, отримати доступ до інших параметрів:

for(i=0;i<5;i++)printf("%d\n',*p++);

Для роботи з функціями, що мають змінну кількість параметрів, використовуються макроси va_start, va_arg та va_ end, визначені у файлі <stdarg.h>. Макрос va_start використовується для ініціалізації відповідного покажчика адресою першого невизначеного параметра, va_arg – для взяття відповідного значення й переходу на наступний параметр, va_ end – для коректного завершення роботи з відповідним покажчиком (обнулення).

Визначаються ці макроси у різних версіях С по-різному. Нижче подано варіант продуктів фірми Microsoft:

typedef char*va_list;

#define va_start(ap,v)

ap=(va_list)&v+sizeof(v)

#define va_arg (ap,t)

((t*)(ap+=sizeof(t)))[-1]

#define va_end(ap)ap=NULL

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

#include <stdio.h>

#include <stdarg.h>

/*обраховує суму аргументів до 0*/