Variable length argument lists in C
A function in C programming can take a variable number of parameters with a variable-length argument list it is also called variadic functions. An ellipsis (…) as the final parameter in the function prototype indicates this capability. A syntax problem is placing the ellipsis in the midst of the list; it should be the last parameter.
To operate with variable-length argument lists, include the header file. A type (va_list) and a collection of macros are provided in this header for accessing the arguments.
The following are needed for variable-length arguments:
- va_list: The va_start, va_arg, and va_end macros use this type to hold data. Define a va_list object to access the arguments.
- va_start: Prior to accessing the arguments in the variable-length list, this macro needs to be called. It sets up the va_list object so that the va_arg and va_end macros can use it. The identifier of the rightmost fixed argument in the parameter list before the ellipsis and the va_list object are the two arguments that the va_start macro accepts. For the macros to function, there must be at least one fixed parameter in the function definition.
- va_arg: The variable-length list’s next parameter value is expanded by this macro. The type of the expected input and the va_list object are passed in as arguments. It is required that your code assume the variable’s type and supply it to va_arg. Every time va_arg is used, the va_list object is changed to point to the subsequent argument.
- va_end: The function whose variable-length argument list va_start alluded to can now return normally with this macro. The variable-length argument list is cleaned up and the va_list object is passed in as an argument.
The fact that there are no macros to tell you how many parameters are on the stack or what kind of parameters they are is a critical feature of using C-style variable-length argument lists. A way to ascertain this must be implemented in your code. The count of the subsequent parameters, for instance, can be specified by the first, mandatory argument. Alternatively, the format string (the first argument needed) can supply the ordered list of variable parameters and their types, as is the case with functions like printf and scanf. When the printf implementation comes across a format specifier, it iterates over the format string and uses va_arg to read the expected type off the stack.
This is an illustration of a function average that determines the average of a variable number of double values, with the count of following arguments indicated by the first argument:
Example
// Using variable-length argument lists
#include <stdarg.h> // Required header for variable arguments
#include <stdio.h>
// Function prototype with ellipsis indicating variable arguments
double average(int i, ...); // ... represents variable arguments
int main(void) {
double w = 37.5;
double x = 22.5;
double y = 1.7;
double z = 10.2;
printf("%s%.1f; %s%.1f; %s%.1f; %s%.1f\n\n",
"w = ", w, "x = ", x, "y = ", y, "z = ", z);
printf("%s%.3f\n%s%.3f\n%s%.3f\n",
"The average of w and x is ", average(2, w, x), // First argument (2) is the count
"The average of w, x, and y is ", average(3, w, x, y), // First argument (3) is the count
"The average of w, x, y, and z is ", average(4, w, x, y, z)); // First argument (4) is the count
}
// calculate average
double average(int i, ...) { // i is the fixed argument before the ellipsis
double total = 0; // initialize total
va_list ap; // Declare a va_list object
va_start(ap, i); // Initialize the va_list object, using the last fixed argument 'i'
// Process variable-length argument list
for (int j = 1; j <= i; ++j) { // Loop based on the count 'i'
total += va_arg(ap, double); // Retrieve the next argument, assuming it's a double
}
va_end(ap); // Clean up the variable-length argument list
return total / i; // calculate average
}
Output
w = 37.5; x = 22.5; y = 1.7; z = 10.2
The average of w and x is 30.000
The average of w, x, and y is 20.567
The average of w, x, y, and z is 17.975
With double explicitly specified as the expected type for each argument, this example shows how the function average utilises the first parameter, i, to determine how many additional arguments to expect before using va_arg to access them. In order to interpret the number and kinds of following arguments, standard library functions like as printf rely on the format string. Despite their flexibility, C-style argument lists can be very risky if the types or quantity of arguments match the function’s expectations.
You can also read What Is The Typedef In C With Code Examples?
You can also read What Are The Features Of C Preprocessor With Examples?