Table of contents
1. What is stdarg.h in C2. Predefined type
3. Macros in stdarg.h
4. Examples of using stdarg.h in C
4.1. A simple variadic function to print integers
4.2. Summation function
4.3. A simplified "print" function
stdarg.h
in C
The stdarg.h
header in C provides functionality for managing variable numbers of function arguments (variadic functions).
This is useful when the number or types of arguments cannot be determined at compile time or when you need a function to accept a flexible set of parameters.
va_list
– Represents an object of type "variable argument list".
Before you can access any of the variable arguments passed to a function, you declare a variable of type va_list
, which internally keeps track of your position among the arguments.
va_start(va_list param, last_fixed_param)
Initializes the traversal of the variable argument list. The first parameter to va_start
is the va_list
that you declared.
The second parameter (last_fixed_param) is the name of the last fixed (non-variadic) parameter in the function’s parameter list.
Important: this macro must never be redefined as a function.
va_arg(va_list param, type)
Expands to an expression that has the specified type and the value of the current argument in the list.
After you call va_arg
, the va_list
is automatically advanced to the next argument.
This macro must never be redefined as a function.
va_end(va_list param)
Terminates the use of the variable argument list. You must call va_end
for every va_list
that was initialized by va_start
(or by va_copy
in some C standards). This macro must be called before exiting the function that uses the variable argument list.
The follwing function demonstrates how to handle a variable number of integer arguments using the stdarg.h
library in C.
It begins by calling va_start
on the va_list
variable, then iterates through the supplied arguments, retrieving each integer in
turn via va_arg
. For each integer, it prints out the argument’s index and value. Finally, it cleans up the list by calling va_end
,
ensuring correct resource management.
#include <stdarg.h>
#include <stdio.h>
void print_integers(int count, ...)
{
va_list args;
va_start(args, count);
for(int i = 0; i < count; i++)
{
// Retrieve an int from the list of arguments
int value = va_arg(args, int);
printf("Value %d: %d\n", i + 1, value);
}
va_end(args);
}
int main(void)
{
print_integers(3, 10, 20, 30);
return 0;
}
#include <stdio.h>
#include <stdarg.h>
int sum(int num_args, ...);
int main(void)
{
printf("Total = %d\n", sum(4, 1, 2, 3, 4));
printf("Another total = %d\n", sum(3, 27, 34, 55));
return 0;
}
int sum(int num_args, ...)
{
int total = 0;
int i;
va_list arg_pointer;
// Initialize arg_pointer to the start of the variable args
va_start(arg_pointer, num_args);
// Loop over the number of arguments, retrieving each one
for (i = 0; i < num_args; i++)
{
int value = va_arg(arg_pointer, int);
total += value;
}
// Clean up
va_end(arg_pointer);
return total;
}
The num_args
parameter indicates how many additional integers to expect. Each va_arg
call
retrieves an int
and increments the internal pointer. Finally, va_end
cleans up after the loop.
Here’s how you might write a minimal function that behaves somewhat like printf
, handling a
format string and multiple arguments:
#include <stdio.h>
#include <stdarg.h>
void imprime(const char *format, ...);
int main(void)
{
int a = 3;
int b = 8;
char message[] = "Hello";
imprime("a=%d b=%d\n", a, b);
imprime("Message=%s\n", message);
return 0;
}
void imprime(const char *format, ...)
{
va_list arg_pointer;
const char *p;
int int_value;
char *str_value;
va_start(arg_pointer, format);
for (p = format; *p != '\0'; p++)
{
if (*p != '%')
{
putchar(*p);
continue;
}
// If it's a '%', get the next character to determine what to print
switch (*++p)
{
case 'd':
int_value = va_arg(arg_pointer, int);
printf("%d", int_value);
break;
case 's':
str_value = va_arg(arg_pointer, char *);
printf("%s", str_value);
break;
default:
// If it's not recognized, just print the character
putchar(*p);
break;
}
}
va_end(arg_pointer);
}
In this example, imprime
iterates over each character of format
. When a '%'
is found, it
checks the next character ('d'
for integers or 's'
for strings) and retrieves the
corresponding argument with va_arg
.
Author
Dr. Roger Ianjamasimanana