-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmain.c
78 lines (58 loc) · 3.89 KB
/
main.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
// Прежде использовался varargs.h, который был объявлен устаревшим.
// Эта функция позволяет вычислить среднее значение от произвольного количества
// аргументов:
double average(int count, ...) {
va_list ap; // stdarg.h объявляет тип va_list.
int j;
double sum = 0;
// Требуется последний известный аргумент
// (чтобы получить адрес первого неизвестного):
va_start(ap, count);
// va_start принимает два аргумента, объект va_list и ссылку на последний
// параметр функции (тот, что перед многоточием). Она инициализирует va_list
// объект для использования в va_arg или va_copy. Компилятор обычно выдает
// предупреждение, если ссылка неверная (например, ссылка на параметры,
// отличающиеся от последнего, или ссылка на совершенно другой объект).
for (j = 0; j < count; j++) { // число параметров передается в первом аргументе.
// Увеличивает ap до следующего аргумента:
sum += va_arg(ap, double); // функция ожидает, что типы будут double.
// va_arg принимает два аргумента, va_list объект (ранее
// инициализированный) и дескриптор типа. Он расширяется на следующей
// переменной аргумент, и имеет указанный тип. Каждый следующий вызов
// возвращает следующий аргумент.
}
// va_end принимает один аргумент типа va_list и очищает его:
va_end(ap);
// Если вы хотели, например, сканировать переменное число аргументов более
// чем один раз, вам надо будет повторно инициализировать va_list путём
// вызова va_end и затем va_start.
return sum / count;
}
// В других случаях, например для функции printf(), число и типы аргументов
// выясняются из строки формата.
//---------------------------------------------------------------------------
void Print(const char *arg, ...) {
va_list arguments;
for (va_start(arguments, arg); arg != NULL; arg = va_arg(arguments, const char *)) {
printf("%s", arg);
}
va_end(arguments);
}
#define mPrint(...) Print(__VA_ARGS__, NULL)
//---------------------------------------------------------------------------
int main(int argc, const char * argv[]) {
printf("---------------------------------------------------------------------------\n");
printf("Ср. знач. 1 + 2 + 3 = %f\n", average(3, 1., 2., 3.)); // Ср. знач. 1 + 2 + 3 = 2.000000
// тип должен точно
// соответствовать тому,
// что указан в va_arg.
printf("---------------------------------------------------------------------------\n");
Print("foo", "bar", NULL); // foobar
printf("\n");
mPrint("fooo", "bar"); // fooobar
printf("\n---------------------------------------------------------------------------\n");
return EXIT_SUCCESS;
}