Fahad Xd
Fahad Xd

Reputation: 13

I want to return multiple values from function using pointers but it's returning one value

I want to return multiple values from user defined function but it's returning only one variable. Here's the code:

#include <stdio.h>
double sum_n_avg(double, double, double, double*, double*);

int main()
{
    double n1, n2, n3, sump, avgp;
    printf("enter numbers:");
    scanf("%lf%lf%lf", &n1, &n2, &n3);

    printf("sum and average is %lf",sum_n_avg(n1, n2, n3, &sump, &avgp));
    return 0;
}

double sum_n_avg(double n1, double n2, double n3, double *sump, double *avgp)
{
    *sump = n1 + n2 + n3;
    *avgp = *sump / 3;

}

Upvotes: 0

Views: 79

Answers (3)

Yunnosch
Yunnosch

Reputation: 26703

You can return two values via pointer-to-output-parameters, as you implemented.
To clean up your code:

  • do not declare a return value if you do not return anything:
    double sum_n_avg( -> void sum_n_avg(, in prototype and definition.
  • call the function before printing, to get the values in the pointed-to variables:
    sum_n_avg(n1,n2,n3, &sump,&avgp); printf(
  • give the variables as values to printf:
    printf("sum is %lf and average is %lf", sump, avgp);

Just noticed that Steve Summit has had the basic know how in his earlier comment. I did not use it (got distracted by missing return), but still credits to him.

Upvotes: 0

You can only return one thing from a function. There are several ways around your specific problem though.

First you can declare two functions, each of which does it's own separate task. This is the recommended design pattern, as it makes your code more logical to the reader.

For this double function, I will take in three doubles, since that is how you have yours set up.

double sum(double a, double b, double c) {
    return (a + b + c);
}

To call this function from main, you would say:

double s = sum(n1,n2,n3);

For your average function, all you then have to do is get the result of the sum function and divide by the number of elements you have, in this case three, of course.

double average(double sum, double n) {
    return (sum / n);
}

Again, to use this function from main, you could do something like this:

double avg = average(s, 3);

Your functions should ideally be more generic to be more useful, but this is a pretty contrived toy example, so I think you get the point.


Now, if you really were absolutely set on returning multiple values from a single function, there are ways to do that as well, although again, recommended programming practices dictate this is a pretty lame idea, but I think you should still know how it would work.

You could declare a struct:

struct descriptiveStatistics {
    double sum;
    double avg;
};

You should keep in mind that you have to instantiate this struct in order to be able to use it, which we would do from main like this:

int main()
{
    double n1, n2, n3;
    struct descriptiveStatistics stats;
    ...

Now to actually return both the average and the sum from a single function, we would combine our two previous functions, like this:

struct descriptiveStatistics analyzeData(double a, double b, double c) {
    struct descriptiveStatistics results;

    results.sum = a + b + c;
    results.avg = sum / 3;

    return results;
}

In this basic example, we're just returning a copy of the struct descriptiveStatistics results struct for simplicity's sake. We could also return a pointer, like this:

struct descriptiveStatistics* analyzeData(double a, double b, double c) {
    struct descriptiveStatistics* results = malloc(sizeof(struct descriptiveStatistics));

    // Remember to check for NULL in case there was an error during dynamic memory allocation
    if (results == NULL) { /** Handle error ... */ }    

    results->sum = a + b + c;
    results->avg = sum / 3;

    return results;
}

Then, from main you would just create the struct and set it like this:

int main()
{
    struct descriptiveStatistics* stats = analyzeData(n1,n2,n3);

    ...

I purposefully didn't use a typedef when I declared the struct because I wanted to deal with one thing at a time, but it might be helpful -and a relief- to know that you don't have to keep typing this super long name over and over. You could do this in the declaration:

typedef struct descriptiveStatistics {
    double sum;
    double avg;
} *Statistics;

This is my preferred way of using typedef. Now, rather than having to type struct descriptiveStatistics* every time, we can now just use Statistics. Note that I made it a pointer to struct descriptiveStatistics, but you could also do typedef struct descriptiveStatistics { ... } Statistics; and this will work exactly the same, except it won't be a pointer obviously.

Upvotes: 1

Achal
Achal

Reputation: 11921

your code having undefined behavior as sum_n_avg() doesn't return anything but printf("sum and average is %lf", ??); expects one value.

But you are expecting something like this

void sum_n_avg(double n1,double n2,double n3,double *sump,double *avgp) {
        *sump=n1+n2+n3;
        *avgp=*sump/3;         
}
int main() {
        double n1,n2,n3,sump,avgp;
        printf("enter numbers:");
        scanf("%lf%lf%lf",&n1,&n2,&n3);

        sum_n_avg(n1,n2,n3, &sump,&avgp); /* call like this */
        printf("sum and average is %lf and %lf\n",sump,avgp);/*sump and avgp gets updated from sum_n_avg() function */
        return 0;
}

Upvotes: 1

Related Questions