Variadic patterns
- C course
- Intermediate
- Lesson 80/116
- 5 min
Learn variadic function patterns.
Variadic patterns
A common variadic pattern: use the first argument as the seed, then process the rest in a loop. This is used in max, min or avg functions.
For max_n: after va_start, read the first va_arg into int max. Then in for (int i = 1; i < count; i++) for each new v = va_arg(args, int) do if (v > max) max = v;. The loop starts at 1 because we already consumed the 0th element. This pattern is the variadic variant of the accumulator pattern. In sum_n we started with total = 0; in max_n we start with the first argument because the max of an empty set is undefined.
The max_n implementation
Let's write a full max_n implementation. The first argument goes into max, then a loop compares each new value.
Definition: int max_n(int count, ...) { va_list args; va_start(args, count); int max = va_arg(args, int); for (int i = 1; i < count; i++) { int v = va_arg(args, int); if (v > max) max = v; } va_end(args); return max; }. The loop starts at 1 because the 0th argument is already in max. Each step reads v and updates max if v is larger. Call: max_n(4, 5, 12, 8, 3) → 12. This pattern works for min_n too by changing > to <. Flexibility is the power of variable arguments.
Practice The max_n function
Write int max_n(int count, ...). va_list args; va_start(args, count);. Start with int max = va_arg(args, int);. In for (int i = 1; i < count; i++) do int v = va_arg(args, int); and if (v > max) max = v;. va_end(args); return max;. In main call printf("%d\n", max_n(4, 5, 12, 8, 3));.
Starter code
#include <stdio.h>
#include <stdarg.h>
// max_n: return the largest of count ints
// declare va_list, init with va_start, set first as max, for with va_arg, update max, va_end
// main: printf("%d\n", max_n(4, 5, 12, 8, 3));
int main(void) {
// write here
return 0;
}Sample solution
#include <stdio.h>
#include <stdarg.h>
int max_n(int count, ...) {
va_list args;
va_start(args, count);
int max = va_arg(args, int);
for (int i = 1; i < count; i++) {
int v = va_arg(args, int);
if (v > max) max = v;
}
va_end(args);
return max;
}
int main(void) {
printf("%d\n", max_n(4, 5, 12, 8, 3));
return 0;
}Expected output
12
Questions and answers
Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.
1 Seed with the first argument
int max = va_____(args, int);
int max = va_arg(args, int);
Explanation: va_arg reads the first value into max.
2 Accumulator patterns
| Term | Meaning |
|---|---|
sum_n |
start with 0 |
max_n |
start with first arg |
print_numbers |
print directly |
log_msg |
via vprintf |
3 Why does the loop in max_n start at 1?
- the first arg was already read Correct answer
- va_arg can't start at 0
- count must be greater than 1
- that's how for loops work
Explanation: The 0th arg was already assigned to max; the loop starts at 1.