1. Functions can be written to handle variable number of arguments. For example, printf().
2. The function prototype should have atleast one known argument followed by ellipsis (set of 3 dots) which represent any unknown number of arguments passed. The ellispsis should only appear as the last aruments.
3. This feature is implemented using a set of macros va_list, va_start, va_arg, va_end, va_copy defined in stdarg.h. All the above macros were defined since C89 except va_copy which is defined since C99.
4. va_list is a type used to declare a pointer to be used by other macros.
5. va_start is a macro which initializes ap to point to the first anonymous argument (unknown argument) which is stored in stack memory. The known argument just before the ellipsis is used by va_start as a reference in the memory to locate the unknown arguments. va_start should be invoked before va_arg.
6. va_arg is a macro which retuns an unknown argument on every call and steps ap to the next argument. var_arg uses type name as its second parameter to determine the return type and step size.
The used can be one of the fully promoted types (int, unsigned int, double), its pointer types and void *. The behaviour of va_arg is undefined if the is not compatible with the actual type if there is no next argument.
7. va_copy is a macro that creates a copy of ap such that the current state of ap is copied.
8. va_end clears the ap so that is no more usable. It must be called before returning from the function.
2. The function prototype should have atleast one known argument followed by ellipsis (set of 3 dots) which represent any unknown number of arguments passed. The ellispsis should only appear as the last aruments.
void function(char var1, int var2, ...);
3. This feature is implemented using a set of macros va_list, va_start, va_arg, va_end, va_copy defined in stdarg.h. All the above macros were defined since C89 except va_copy which is defined since C99.
4. va_list is a type used to declare a pointer to be used by other macros.
va_list ap;
5. va_start is a macro which initializes ap to point to the first anonymous argument (unknown argument) which is stored in stack memory. The known argument just before the ellipsis is used by va_start as a reference in the memory to locate the unknown arguments. va_start should be invoked before va_arg.
va_start(ap, var2);
6. va_arg is a macro which retuns an unknown argument on every call and steps ap to the next argument. var_arg uses type name as its second parameter to determine the return type and step size.
temp = va_arg(ap, );
The used can be one of the fully promoted types (int, unsigned int, double), its pointer types and void *. The behaviour of va_arg is undefined if the is not compatible with the actual type if there is no next argument.
7. va_copy is a macro that creates a copy of ap such that the current state of ap is copied.
va_copy(ap, ap_copy);
8. va_end clears the ap so that is no more usable. It must be called before returning from the function.
va_end(ap);
Example:
#include <stdio.h>
#include <stdarg.h>
int add(int c, ...);
int main()
{
int res1, res2, res3, res4;
res1 = add(3, 1, 2, 3);
res2 = add(5, 1, 2, 3, 4, 5);
res3 = add(7, 1, 2, 3, 4, 5, 6, 7);
res4 = add(9, 1, 2, 3, 4, 5, 6, 7, 8, 9);
printf("res1 = %d\nres2 = %d\nres3 = %d\nres4 = %d\n",
res1, res2, res3, res4);
}
int add(int count, ...)
{
int sum = 0, sum2 = 0;
va_list valist, valist2;
va_start(valist, count);
while (count) {
if (count == 2)
va_copy(valist2, valist);
sum += va_arg(valist, int *);
if (count <=2)
sum2 += va_arg(valist2, int);
--count;
}
return sum;
}
Reference:
1. K&R - Sec 7.3, Appendix B7
2. c99 - Sec 4.8
No comments:
Post a Comment
Comment will be published after moderation only. Do not advertise here.