Thursday 10 March 2011

Variable length argument lists

I wrote my midterm for computer programming today and a good portion of it focused on variable length argument lists. What is that you may ask? Well take a look at a random function:

int square(int x)
{
    return x*x;
}
This function takes one argument - an integer which is multiplied by itself to give its square.
Now let's look at C's function printf() which is used to print text to the command prompt. We could simply tell it to print a string:

printf("Hello");

or we could use to print a value stored in a variable:

int x=6;
printf("The value of x is %d",x);

we can do as many variables as we want!

int x=3;
float y=6.3;
printf("%d %f",x,y);

Now if you're like me when I started out with C, you're probably thinking "How does the function know when to stop printing, and what types of variables to expect?" Well we're not going to write out the implementation of printf() as that takes numerous cross-referencing libraries, but we are going to do a function with a variable length argument list that finds the average of a unspecified number of numbers.
The required functions are stored in stdarg.h so we first need to include that:

#include <stdarg.h>

Now that we have the proper tools, let's look at how a variable argument list is created. There are 4 main "tools" we will be using:

1) va_list identifier
This declares a variable of type va_list. This is sort of like a pointer to your arguments.

2) va_start(identifier, first argument)
This tells the list where we're starting. The obvious location is the first argument. Note that you must have at least one defined parameter when dealing with variable length argument lists (more on this later)

3) va_arg(indentifiertype)
This is what we will be using to acquire the values form our arguments. Note that the identifier used here is the same one used to declare our va_list

4) va_end(identifier)
This is just to clean up nicely. It tells our program "Ok, we're done with this list of arguments, let's clean up now"

So now that we've defined the necessary tools, let's get to the implementation of the function:

float average(int n,...)
{
    float sum=0;
    va_list arg;
    va_start(arg,n);
    
    for(int i=0;i<n;i++)
    {
        sum+=va_arg(arg,float);
    }
    va_end(arg);
    return sum/n;
}

So let's go through it bit by bit:
When declaring a function with a variable length argument list, you MUST have at least one definitive argument. In this case, we are taking that argument to be the number of numbers we would like to average. As we all know, to average numbers, you take the sum of the numbers (float sum), and then divide it by the amount of numbers you have (int n).
So we start off by declaring our va_list and initializing the va_start(). Note that after suing va_start, the pointer now points at the 2nd argument (if available).
Next is our for loop which will loop n times to sum up all the integers. After doing that, we call va_end() to clean up. And then return sum/n, which will be our average!

A sample call of this function could be:

float x = average(3,6,4,5);

In which case, the value of x would be 5 since (4+5+6)/3 = (15/3) = 5

I hope this has been useful! I just thought I would share this piece of information with everyone!

14 comments:

  1. Awesome tutorial/ run through of variable length arguments. If possible you could do one of how to do this iteratively.

    ReplyDelete
  2. I really wish I knew C++. xP
    Good article too got you a new follower!

    ReplyDelete
  3. I wish I knew this blog when I was into emulating games, and making mini games for graphing calculators

    ReplyDelete
  4. Variable argument lists are pretty cool.
    You mention you're in Computer classes, have you played around with the C++ Vector package at all? It's gobs of fun, simple, but powerful.

    ReplyDelete
  5. I have to learn c++ for college. i will most definitely be coming to you for help.

    ReplyDelete
  6. Nice. C++ is on my list of to learn. Following you as this seems like it will be helpful.

    ReplyDelete
  7. I know PHP but this is nothing like that xD How long have you been doing C++?

    ReplyDelete
  8. Good lord. I didn't understand any of that.

    ReplyDelete
  9. Good post! Gunna read all of it a bit later, totally following. =)

    ReplyDelete
  10. Ah nice, I took a class in high school its good to refresh my memory

    ReplyDelete