Search code examples
arrayscpointersvariadic-functions

Variadic function with pointers as parameters


The program should print the sum of the first three, five, and eight elements of a given array(size 8). I've been able to do it passing pointers in the main function like this:

code:

#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
int  sum (int count,int data[],...) {
    int res=0;
    for(int i=0;i<count;i++)
    {
        res=res+data[i];   
    }
    return res;
}
int main(){
    int elements[8]={11,2,33,5,8,48,2,-8};
    int three_elements;
    int five_elements;
    int eight_elements;
    three_elements=sum(3, &elements[0], &elements[1], &elements[2]);
    five_elements=sum(5, &elements[0], &elements[1], &elements[2], &elements[3], &elements[4]);
    eight_elements=sum(8, &elements[0], &elements[1], &elements[2], &elements[3], &elements[4],&elements[5], &elements[6], &elements[7]);
    printf("First Three elements sum:%d\n",three_elements);
    printf("First five elements sum:%d\n",five_elements);
    printf("First eight elements sum:%d",eight_elements);
    return 0;
}

OUTPUT:

First Three elements sum:46
First five elements sum:59
First eight elements sum:101

How can I do it by passing the parameters straight into the sum function? I tried to do it like this but the compiler keeps giving me errors:

code:

#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
int  sum (int count,int* data[],...) {
    int res=0;
    for(int i=0;i<count;i++)
    {
        res=res+data[i];   
    }
    return res;
}
int main(){
    int elements[8]={11,2,33,5,8,48,2,-8};
    int three_elements;
    int five_elements;
    int eight_elements;
    three_elements=sum(3, elements[0], elements[1], elements[2]);
    five_elements=sum(5, elements[0], elements[1], elements[2], elements[3], elements[4]);
    eight_elements=sum(8, elements[0], elements[1], elements[2], elements[3], elements[4],elements[5], elements[6], elements[7]);
    printf("First Three elements sum:%d\n",three_elements);
    printf("First five elements sum:%d\n",five_elements);
    printf("First eight elements sum:%d",eight_elements);
    return 0;
}

Solution

  • Sum of variadic function

    Take a look at the man:

    The va_start() macro initializes ap for subsequent use by va_arg() and va_end(), and must be called first.

    The va_arg() macro expands to an expression that has the type and value of the next argument in the call. The argument ap is the va_list ap initialized by va_start(). Each call to va_arg() modifies ap so that the next call returns the next argument. The argument type is a type name specified so that the type of a pointer to an object that has the specified type can be obtained simply by adding a * to type.

    Without pointers you can do it the following way:

    #include <stdlib.h>
    #include <stdio.h>
    #include <stdarg.h>
    
    int  sum (int len, int value, ...) {
        va_list args; // initialize va_list
    
        int res = value;
        va_start(args, value); // start va
        for (int i = 1; i < len; i++) // iterate over other arguments
            res += va_arg(args, int); // add the next argument to res
        va_end(args); // don't forget to end va
        return res;
    }
    int main(){
        int elements[8]={11,2,33,5,8,48,2,-8};
        int three_elements;
        int five_elements;
        int eight_elements;
        three_elements=sum(3, elements[0], elements[1], elements[2]);
        five_elements=sum(5, elements[0], elements[1], elements[2], elements[3], elements[4]);
        eight_elements=sum(8, elements[0], elements[1], elements[2], elements[3], elements[4],elements[5], elements[6], elements[7]);
        printf("First Three elements sum:%d\n",three_elements);
        printf("First five elements sum:%d\n",five_elements);
        printf("First eight elements sum:%d\n",eight_elements);
        return 0;
    }
    

    In order to get the sum through the pointers you can do it the following way:

    #include <stdlib.h>
    #include <stdio.h>
    #include <stdarg.h>
    
    int  sum (int len, int *value, ...) {
        va_list args; // initialize va_list
    
        int res = *value;
        va_start(args, *value); // start va
        for (int i = 1; i < len; i++) // iterate over other arguments
            res += (int)*va_arg(args, int*); // add the next argument to res
        va_end(args); // don't forget to end va
        return res;
    }
    int main(){
        int elements[8]={11,2,33,5,8,48,2,-8};
        int three_elements;
        int five_elements;
        int eight_elements;
        three_elements=sum(3, &elements[0], &elements[1], &elements[2]);
        five_elements=sum(5, &elements[0], &elements[1], &elements[2], &elements[3], &elements[4]);
        eight_elements=sum(8, &elements[0], &elements[1], &elements[2], &elements[3], &elements[4], \
            &elements[5], &elements[6], &elements[7]);
        printf("First Three elements sum:%d\n",three_elements);
        printf("First five elements sum:%d\n",five_elements);
        printf("First eight elements sum:%d\n",eight_elements);
        return 0;
    }
    

    Output:

    First Three elements sum:46
    First five elements sum:59
    First eight elements sum:101