In my last
post, I was talking about the printf function and there I said that printf
uses ellipsis operator. In this post I would like to elaborate on how to use
ellipsis in C program.
a. Here are some important points on
Ellipsis
b. Ellipsis operator is expressed
only with three dots (…) within the argument list of a function
c. Ellipsis must be the last
argument in the argument list
d. The argument list containing the
ellipsis must have at least another argument (other than the ellipsis) in the
list. Let us call it as “Mandatory Argument”.
This Mandatory Argument must be
placed just before the ellipsis and this Mandatory Argument must reflect the
number of variable arguments currently being passed explicitly or implicitly.
Here I mean to say, Mandatory
Argument can explicitly say that currently n numbers of variable arguments are
being passed; in this case the prototype of the function would be something
like
void foo(int no_of_variable_arguments,
…)
Otherwise Mandatory argument may
hide this information within any sort of other data types. For example if the
numbers of variable arguments is an element of a structure of type Info, then a
valid prototype would be
void foo(struct Info str, …)
If the numbers of variable
arguments are passed implicitly then it becomes the responsibility of foo to
determine (within the body code of foo) what the value of n from the given
container is.
Let us take some more examples
void foo(int var1, int num, …)
is a valid usage of ellipsis. Here num is working as Mandatory argument and the
numbers of variable arguments actually being passed must be explicitly /
implicitly determined through num. var1 is nothing but the optional argument ,
which might be there for any good reasons.
void foo( char* str, …)
is again valid. Here the numbers of variable arguments being passed must be
hidden within string str. parsing of str will give you the required value of n.
The logic of parsing must be maintained within foo
Let us do a case study on our
good old friend printf
The signature of printf is like
int printf(const char* formatString, …)
Here Mandatory Argument does the
trick to hide the numbers and types of variable arguments currently being
passed. For example if I call printf
like printf(“The results are %d, %d and %f”, I,j,k); then
the string “The
results are %d, %d and %f” will implicitly say that there are
three variable arguments that are being passed now and they are i, j and k. The
proper parsing algorithm in printf will be able to count the numbers of format
specifiers like %d or %f and this obviously hides the data types of variable
arguments also. Parsing of “The results are %d, %d and %f” essentially
says that there would be three variable arguments and out of these three
variable arguments, first two are ints and the third one is float .
Now let us go straight to “how to
write the body of the function containing ellipsis as an argument”.
Ellipsis works with four
different macros to deal with variable number of arguments; and they are
va_list, va_start, va_arg and va_end. The va_list stores the variable
arguments. The list is declared like
va_list anyList;
The va_start takes two arguments,
the va_list itself and the Mandatory Argument. If the Mandatory Argument passed
to the experimental function be integer x, then the call to va_start would be
va_start( anyList, x );
va_start initializes the va_list.
Next va_arg also takes two
arguments, va_list itself with a particular data type. For example
va_arg(anyList,float);
Calling of this macro returns the
next float from the anyList.
Ultimately, va_end(anyList) will clean up anyList.
CODE EXAMPLE
The following
code example shows how to write a function with variable number of arguments.
The
code is self
explanatory through commenting. Please give proper attention to the comment in
red.
#include<stdio.h>
#include<stdlib.h>
#include <stdarg.h>
//defining the function with variable number of arguments
float findAverage(int numArg, ...)
{
float avg;
int sum = 0;
int arg;
int index;
va_list list;
//creating the variable list
va_start(list,numArg);
// initializing the list with numAg number of arguments
for( index = 0 ;
index < numArg; index++ )
{
arg =
va_arg( list, int );//retrieving
the arguments. The prior knowledge of the argument is mandatory. Here in this
case it is “int”
sum = sum + arg;
}
avg = sum / numArg;
va_end(list);
//clearing up the list
return avg;
}
int main(void)
{
//calling the
function with variable number of arguments
printf("\n The
average of 3, 4, 5 = %f\n", findAverage(3,3,4,5) );
printf("\n The
average of 6,7,8,9,10 = %f\n", findAverage(5,6, 7, 8, 9, 10));
return 0;
}
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.