tags:

views:

427

answers:

8

if i have a function that produces a result int and a result string how do i return them both from a function? as far as i can tell i can only return 1 thing, as determined by the type preceding the function name

+2  A: 

create a struct and set 2 values inside and return the struct variable.

struct result {
    int a;
    char *string;
}

you have to allocate space for the char * in your program.

sza
A: 

Use pointers as your function parameters. Then use them to return multiple value.

Bloodlee
+13  A: 

I don't know what your string is, but I'm going to assume that it manages its own memory.

You have two solutions:

1: Return a struct which contains all the types you need.

struct Tuple {
    int a;
    string b;
};

struct Tuple getPair() {
    Tuple r = { 1, getString() };
    return r;
}

void foo() {
    struct Tuple t = getPair();
}

2: Use pointers to pass out values.

void getPair(int* a, string* b) {
    // Check that these are not pointing to NULL
    assert(a);
    assert(b);
    *a = 1;
    *b = getString();
}

void foo() {
    int a, b;
    getPair(&a, &b);
}

Which one you choose to use depends largely on personal preference as to whatever semantics you like more.

Travis Gockel
I think it depends more on how related the return values are. If the int is an error code and the string is a result, then these should not be put together in a struct. That's just silly. In that case, I would return the int and pass the string as a `char *` and a `size_t` for the length unless it's absolutely vital for the function to allocate it's own string and/or return `NULL`.
Chris Lutz
@Chris I agree with you completely, but I have no idea of the usage semantics of the variables he needs.
Travis Gockel
+2  A: 

Two different approaches:

  1. Pass in your return values by pointer, and modify them inside the function. You declare your function as void, but it's returning via the values passed in as pointers.
  2. Define a struct that aggregates your return values.

I think that #1 is a little more obvious about what's going on, although it can get tedious if you have too many return values. In that case, option #2 works fairly well, although there's some mental overhead involved in making specialized structs for this purpose.

James Thompson
C doesn't have references ;-), although since the poster used `string`, it might be safe to assume C++...
Travis Gockel
Totally forgot about that! I modified my answer to use pointers, but I've clearly been in C++ land for too long. :)
James Thompson
+2  A: 

Since one of your result types is a string (and you're using C, not C++), I recommend passing pointers as output parameters. Use:

void foo(int *a, char *s, int size);

and call it like this:

int a;
char *s = (char *)malloc(100); /* I never know how much to allocate :) */
foo(&a, s, 100);

In general, prefer to do the allocation in the calling function, not inside the function itself, so that you can be as open as possible for different allocation strategies.

Jesse Beder
+2  A: 

Option 1: Declare a struct with an int and string and return a struct variable.

struct foo {    
 int bar1;
 char bar2[MAX];
};

struct foo fun() {
 struct foo fooObj;
 ...
 return fooObj;
}

Option 2: You can pass one of the two via pointer and make changes to the actual parameter through the pointer and return the other as usual:

int fun(char *param) {
 int bar;
 ...
 strcpy(param,"....");
 return bar;
}

or

 char* fun(int *param) {
 char *str = /* malloc suitably.*/
 ...
 strcpy(str,"....");
 *param = /* some value */
 return str;
}

Option 3: Similar to the option 2. You can pass both via pointer and return nothing from the function:

void fun(char *param1,int *param2) {
 strcpy(param,"....");
 *param2 = /* some calculated value */
}
codaddict
Regarding option 2, you should also pass in the string's length. `int fun(char *param, size_t len)`
Chris Lutz
Now that depends on what the function is doing. If we know what kind of result the function stuffs into the char array, we could just allocate enough space for it and pass it to the function. No need of passing the length. Something similar to how we use `strcpy` for example.
codaddict
+1  A: 

passing parameters by reference to function

exaples:

 void incInt(int *y)
 {
 (*y)++;  // Increase the value of 'x', in main, by one
 }

also by using global variables but it is not recommended

example:

int a=0;

void main(void)
{
//any thing you want to code
} 
moon
`void main(void)` OH HOW IT BURNS!
Chris Lutz
what do you mean? @ Chris Lutz
moon
@moon: `main` is supposed to return a status code. Under *nix, it's more usual to declare it as `int main(int argc, char *argv[])`, I believe Windows has similar conventions.
Duncan
A: 

You can use pass by reference.

Coder
Not in C, you can't.
Duncan
Yes you can in C. C is all about pointers
Gerhard