17

Can anyone tell me how to return multiple values from a function?
Please elaborate with some example?

BenMorel
  • 34,448
  • 50
  • 182
  • 322
Shweta
  • 5,198
  • 11
  • 44
  • 58
  • 1
    For future reference, this is an overly broad duplicate of [How do I return multiple values from a function in C?](https://stackoverflow.com/q/2620146/364696) for the "return fixed count of possibly heterogenous types" case. A number of questions dup-ed to this question should really be dup-ed to that one instead. – ShadowRanger Mar 25 '19 at 19:33
  • @AnttiHaapala: Don't have the tag badge, so I can't do it personally, but that would make sense. I've voted to do so, need more votes though. If you have the hammer, you might go through the linked questions and redirect the dups that should really go elsewhere. – ShadowRanger Mar 25 '19 at 19:38

8 Answers8

20

Your choices here are to either return a struct with elements of your liking, or make the function to handle the arguments with pointers.

/* method 1 */
struct Bar{
    int x;
    int y;
};

struct Bar funct();
struct Bar funct(){
    struct Bar result;
    result.x = 1;
    result.y = 2;
    return result;
}

/* method 2 */
void funct2(int *x, int *y);
void funct2(int *x, int *y){
    /* dereferencing and setting */
    *x  = 1;
    *y  = 2;
}

int main(int argc, char* argv[]) {
    struct Bar dunno = funct();
    int x,y;
    funct2(&x, &y);

    // dunno.x == x
    // dunno.y == y
    return 0;
}
mike3996
  • 17,047
  • 9
  • 64
  • 80
18

You can't do that directly. Your options are to wrap multiple values into a struct, or to pass them in as pointer arguments to the function.

e.g.

typedef struct blah
{
    int a;
    float b;
} blah_t;


blah_t my_func()
{
    blah_t blah;
    blah.a = 1;
    blah.b = 2.0f;
    return blah;
}

or:

void my_func(int *p_a, float *p_b)
{
    *p_a = 1;
    *p_b = 2.0f;
}
netcoder
  • 66,435
  • 19
  • 125
  • 142
Oliver Charlesworth
  • 267,707
  • 33
  • 569
  • 680
8

First of all, take a step back and ask why you need to return multiple values. If those values aren't somehow related to each other (either functionally or operationally), then you need to stop and rethink what you're doing.

If the various data items are part of a larger, composite data type (such as a mailing address, or a line item in a sales order, or some other type described by multiple attributes), then define a struct type to represent a single value of that composite type:

struct addr { // struct type to represent mailing address
  char *name;
  int streetNumber;
  char *streetName;
  char *unitNumber; 
  char *city;
  char state[3];
  int ZIP;
};

struct addr getAddressFor(char *name) {...}

struct point2D {
  int x;
  int y;
};

struct polygon2D {
  size_t numPoints;
  struct point2D *points;
};

struct point2D getOrigin(struct polygon2D poly) {...}

Do not define a struct to collect random items that aren't somehow related to each other; that's just going to cause confusion for you and anyone who has to maintain your code down the road.

If the data items are not functionally related, but are somehow operationally related (e.g. data plus a status flag plus metadata about the operation or items as part of a single input operation), then use multiple writable parameters. The most obvious examples are the *scanf() functions in the standard library. There are also the strtod() and strtol() functions, which convert a string representation of a number; they return the converted value, but they also write the first character that was not converted to a separate parameter:

char *str = "3.14159";
double value;
char *chk;

value = strtod(str, &chk);
if (!isspace(*chk) && *chk != 0)
  printf("Non-numeric character found in %s\n", str);

You can combine these approaches; here's an example inspired by some work I'm currently doing:

typedef enum {SUCCESS, REQ_GARBLED, NO_DATA_OF_TYPE, EMPTY, ERROR} Status;

typedef struct bounds {...} Bounds; 

tyepdef struct metadata {
  size_t bytesRead;
  size_t elementsRead;
  size_t rows;
  size_t cols;
} Metadata;

typedef struct elevations {
  size_t numValues;
  short *elevations;
} Elevations;

Elevations elevs;
Metadata meta;
Bounds b = ...; // set up search boundary

Status stat = getElevationsFor(b, &elevs, &meta);

The service that I request elevation data from returns a 1-d sequence of values; the dimensions of the array are returned as part of the metadata.

John Bode
  • 119,563
  • 19
  • 122
  • 198
5

You can do it using structures:

#include <stdio.h>

struct dont { int x; double y; };

struct dont fred(void)
{
        struct dont b;
        b.x = 1;
        b.y = 91.99919;
        return b;
}

int main(int argc, char **argv)
{
        struct dont look = fred();
        printf("look.x = %d, look.y = %lf\n", look.x, look.y);
        return 0;
}
Michael Foukarakis
  • 39,737
  • 6
  • 87
  • 123
  • 1
    +1 For using independent variables where possible to show all the separate parts of the problem, and for posting a whole program – jellies Apr 28 '16 at 06:00
3

You cannot return multiple values from a C function. You can either

  1. Return a data structure with multiple values, like a struct or an array.
  2. Pass pointers to the function and modify the values of the pointers inside the function. You need to pass x number of pointers where x is the number of return values you need
arbithero
  • 426
  • 3
  • 13
1

To return multiple values from a function we should use a pointer. Here is an example through which you can understand it better

int* twoSum(int* nums, int numsSize, int target) {

int i,j,*a;
a=(int*)malloc(2*sizeof(int));
for(i=0;i<numsSize;i++)
for(j=i+1;j<numsSize;j++)
if(nums[i]+nums[j]==target)
 {
     a[0]=i;
     a[1]=j;
 return a;
 }

}

armatita
  • 12,825
  • 8
  • 48
  • 49
sumit
  • 19
  • 1
0

I´m a beginner in C, so I don´t have experience with array, pointer, structure. To get more than one value from my function I just used a global variable.

Here is my code:

#include <stdio.h>

double calculateCharges( double hourCharges );

// Global variable for totalCharges-function and main-function interaction
double totalCharges = 0;

int main ( void ) {

    double car1 = 0;
    double car2 = 0;
    double car3 = 0;
    double totalHours = 0;

    printf( "%s", "Hours parked for Car #1: ");
    scanf( "%lf", &car1 );

    printf( "%s", "Hours parked for Car #2: ");
    scanf( "%lf", &car2 );

    printf( "%s", "Hours parked for Car #3: ");
    scanf( "%lf", &car3 );

    totalHours = car1 + car2 + car3;

    printf( "%s", "Car\tHours\tCharge\n");

    printf( "#1\t%.1f\t%.2f\n", car1, calculateCharges( car1 ));
    printf( "#2\t%.1f\t%.2f\n", car2, calculateCharges( car2 ));
    printf( "#3\t%.1f\t%.2f\n", car3, calculateCharges( car3 ));
    printf( "TOTAL\t%.1f\t%.2f\n", totalHours, totalCharges);
}

double calculateCharges( double hourCharges ) {

    double charges = 0; 

    if( hourCharges <= 3.0 ) {
        charges = 2;
    } else if ( hourCharges >= 24.0) {
        charges = 10.00;
    } else {
        charges = ((hourCharges - 3.0)*0.5) + 2.0;
    }

    totalCharges += charges;

    return charges;

}
Luca
  • 221
  • 2
  • 11
  • If this works, Great! Go on your merry way and ignore me. But if you feel like listening, PLEASE DON'T USE GLOBAL VARIABLES! it means that you can get nasty results if you ever call a variable by that name and don't realize it's taken, or you have two functions both borrowing that variable, etc... There are better ways to solve the problem at hand, and i suggest you learn them. – jellies Apr 28 '16 at 06:18
  • A few years later, I have to tell you @Stegosaurus, you were right – Luca Nov 23 '20 at 08:10
-2

Method 1 is using array

Method 2 is using pointer

Method 3 is using structure

Akshaya Moorthy
  • 309
  • 3
  • 11