{ …
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*/
void sum(char *msg,...)
{
int total=0;
va_list ap;
int arg;
va_start(ap,msg);
while((arg=va_arg(ap,int))!=0) {
total+=arg;
}
printf(msg,total);
va_end(ap);
}
int main(void) {
sum("Сума 1+2+3+4 є %d\n",1,2,3,4,0);
return 0;
}
Рекурсія
Функції С можуть використовуватись рекурсивно. Це означає, що функція може звертатись сама до себе. Розглянемо класичну програму, що друкує число у вигляді рядка символів:
printd(n) /*print n in decimal
*(recursive)*/
int n;
{
int i;
if(n<0) {
putchar('-');
n=-n;
}
if((i=n/10)!=0)
printd(i);
putchar(n%10+'0');
}
Коли функція викликає себе рекурсивно, то при кожному звертанні утворюється новий набір усіх автоматичних змінних. Таким чином, у printd(123) перша функція printd має n=123. Вона передає 12 другій printd, а коли та повертає керування їй, друкує 3. Точно так само друга printd передає 1 третій, яка її друкує, а потім друкує 2.