Passing variable number of arguments to a C/C++ function like printf().





Introduction



Many of us might have wondered at sometime or the other about how to pass a variable number of arguments to C++ functions : something like a printf function. I don't know how many are aware of this, so I decided to post an article on this topic.

Background



When a function is declared, the data-type and number of the passed arguments are usually fixed at compile time. But sometimes we require a function that is able to accept a variable number of arguments. The data-type and/or number of the passed arguments are provided at the run-time.

Through this article, I will try to show you how to create a C function that can accept a variable number of arguments.

The secret to passing variable number and type of arguments is the stdarg library. It provides the va_list data-type, which can contain the list of arguments passed into a function.
The stdarg library also provides several macros : var_arg, va_start, and va_end that are useful for manipulating the argument-list.

Functions of the macros :
(1) va_start is a macro used to initialize the argument list so that we can begin reading arguments from it. It takes two arguments : (a) the va_list object which stores the passed arguments, and (b) the last named argument, after which the number of arguments is variable.
(2) va_arg is the macro used to read an argument from the list. It takes two parameters: (a) the va_listobject we created, and (b) a data type. va_arg returns the next argument as this type.
(3) va_end is a macro that cleans up our va_list object when we're done with it.

The code



I will clarify the concept with 2 examples.

Example 1 : A function accepts variable arguments of known data-type
(A simple average function, that takes variable number of arguments)



#include <stdio.h>
#include <stdarg.h>

float avg( int Count, ... )
{
      va_list Numbers;
      va_start(Numbers, Count);
      int Sum = 0;
      for(int i = 0; i < Count; ++i )
            Sum += va_arg(Numbers, int);
      va_end(Numbers);
      return (Sum/Count);
}

int main()
{
      float Average = avg(10, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
      printf("Average of first 10 whole numbers : %f\n", Average);
      return 0;
}



Output of the above code is :
Average of first 10 whole numbers : 4.000000



Example 2 : A function accepts variable arguments of unknown data-type
(A simple print function, that takes variable number and variable type of arguments)



#include <stdio.h>
#include <stdarg.h>

float Print( const char* Format, ... )
{
      va_list Arguments;
      va_start(Arguments, Format);
      double FArg;
      int IArg;
      for(int i = 0; Format[i] != '\0'; ++i )
      {
            if (Format[i] == 'f')
            {
                  FArg=va_arg(Arguments, double);
                  printf("Caught a float : %.3lf\n",FArg);
            }
            else if (Format[i] == 'i')
            {
                  IArg=va_arg(Arguments, int);
                  printf("Caught an integer : %d\n",IArg);
            }
      }
      va_end(Arguments);
}

int main()
{
      Print("This is funny, isn't it ?", 1, 2, 12.1200, 3, 4);
      return 0;
}



Output of the above code is :
Caught an integer : 1
Caught an integer : 2
Caught a float : 12.120
Caught an integer : 3
Caught an integer : 4


Hope this article will be useful to you.

Thanx for reading it ! 

Good bye and take care ! 

Comments

Popular posts from this blog

C++ Guidelines for Multithreaded System

Signalling System #7(SS7) Protocol.

std::shared_ptr