0

Consider the following code:

#include<stdio.h>
#include<stdarg.h>
int sum(int, ...);
int main()
{
    int a;
    a=sum(10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
    printf("the sum is %d", a);
    return 0;
}

int sum(int a, ...)
{
    int s=0, i=1;
    va_list ls;
    va_start(ls, a);

    while(i<=a)
    {
        s=s+va_arg(ls, int);
        i++;
    }
    va_end(ls);
    return s;
}

The above code computes the sum of first 10 natural numbers, by using the variable arguments, by sum function. a the first argument of sum, it is specified that the user is giving 10 natural numbers whose sum is needed but I want some way so that we can find the sum without giving the count of the numbers I'm going to add. I means

 sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

will calculate the sum of the first 10 natural numbers which is 55. Please find a way and tell me

Nimit Bhardwaj
  • 827
  • 9
  • 19
  • And why should I tell you? What did you _research_? – Sourav Ghosh Dec 22 '15 at 07:37
  • Please read [Ask] page first. – Sourav Ghosh Dec 22 '15 at 07:38
  • 2
    There *is* no way of getting the number of arguments for a variable-argument function. You either need to provide the number of arguments (like you do), use e.g. a formatting string (like `printf` and `scanf`), or use a special terminator value. – Some programmer dude Dec 22 '15 at 07:38
  • I tried to find it on the book The Standard Library by PL Plouger, I didn't find it and also tried on net I was not able to understand – Nimit Bhardwaj Dec 22 '15 at 07:39
  • Even just googling c varargs and clicking the first hit is more than enough for your question. Shows complete lack of research. If you don't understand something, ask a more detailed question of what you don't understand instead of asking for a solution to your homework. – SBI Dec 22 '15 at 07:41
  • Its not homework, reading just for extra knowledge, – Nimit Bhardwaj Dec 22 '15 at 07:42
  • 3
    If you don't want to provide a count, then you probably need to control it by including an end marker, such as `-1`. Then just stop when you reach it. This will only work, of course, if you can guarantee that the end marker can never appear as a legitimate argument. – Tom Karzes Dec 22 '15 at 07:48
  • Yes sir Tom, This was a good way. – Nimit Bhardwaj Dec 22 '15 at 07:58

1 Answers1

1

Your example is not a good use case for variadic arguments. You buy the flexibility of summing an arbitrary number of values at the cost of type safety. Your code must also rely on either specifying the number of arguments or on providing a sentinel value. (There are methods to check such things in static analysis, but they are compiler dependent.)

But when do you need to sum arbitrary lists of values in C? In C, data is organised in arrays. So the C way to do what you want is:

int array_sum(int a[], size_t n)
{
    int sum = 0;

    while (n--) sum += a[n];        
    return sum;
}

If you want, you can turn this into a variadic function with a variadic macro that uses C99 compound literals and the countof macro, which determines the size of an array:

#define SUM(...) array_sum((int[]){__VA_ARGS__}, \
    sizeof((int[]){__VA_ARGS__}) / sizeof((int[]){__VA_ARGS__}[0]))

Now you can use both arrays and variadic lists:

int a[] = {1, 2, 3, 4, 5, 6};

printf("%d\n", array_sum(a, 6));
printf("%d\n", SUM(1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
printf("%d\n", SUM(0xff, 1ull, 0.0));

Note how the non-integers are converted to signed integers before summing with the usual rules. The <stdarg.h> approach will not work in this case, because the function relies on all parameters being ints, but it has no means of enforcing that.

M Oehm
  • 28,726
  • 3
  • 31
  • 42