Reputation: 185
i have been trying to figure out ways where i can return more than one value from a function in C.
Say for instance i have the
int compute(int a, int b)
{
int c;
// do some computation on a,b,c
// return a,b,c
}
now i can return these values say in an array, and i was trying to do that and i then i realized that the array needs to be dynamic so it can be referenced in main() as well.
Another way could be that i create a structure and then just return the struct variable.
Is there any simple and robust way of doing this, other than the above work around ? i have to return about 25 different computation values which are independent of each other from a method, and i have a lot structs in my code already.
Thank you.
Upvotes: 0
Views: 5281
Reputation: 4248
You can also return array using pointers here is the demonstration. http://www.tutorialspoint.com/cprogramming/c_return_arrays_from_function.htm
Upvotes: 0
Reputation: 502
No you cannot but another alternative solution that is more c++ish would be to create a struct then return that.
struct RET_TYPE
{
int a;
int b;
};
struct RET_TYPE foo()
{
...
return RET_TYPE();
}
Upvotes: 0
Reputation: 102046
You can't easily return more than one variable like, for example, Python with return (a,b,c)
. However you can pass pointers that are set to the other "return values" or use a struct.
If you want a function to actually return separate values and not modify its arguments, a simple way is to pass additional pointers (you could also use structs). e.g. this function will compute the sum and difference of a pair of numbers:
int add_sub(int a, int b, int* ret2) {
if (ret2) *ret2 = a - b;
return a + b;
}
The if (ret1)
allows you to safely pass NULL
as the pointer argument, so that you can ignore that return value. You use this like:
int add, sub;
add = add_sub(10, 3, &sub);
// add == 13, sub == 7
int just_add;
just_add = add_sub(15, 5, NULL);
// just_add == 20
(Note, this technique can lead to confusing behaviour if you pass the same argument twice, e.g. a = add_sub(a, b, &b)
doesn't give you what want.)
If you want to modify the arguments to a function, you can just pass those as pointers. e.g. this function will increment both its arguments and then return their sum:
int increment_and_sum(int* a, int* b) {
(*a)++;
(*b)++;
return a + b
}
Which you use like:
int a = 10, b = 3, sum;
sum = increment_and_sum(&a, &b);
// a == 11, b == 4, sum == 15
(Note that you can't use literals in increment_and_sum
, that is, you can't do increment_and_sum(3, 4)
or increment_and_sum(&3, &4)
.)
Upvotes: 6
Reputation: 6882
The normal way to do it is with pointer arguments. If you need to return variable numbers of things, you can use a pointer to data and a pointer to an integer "number of things". Another way to do it is pointer-to-pointer, and have your function allocate memory as needed. This makes the caller responsible for freeing it.
Example:
int make_numbers(int **numbers, int *count)
{
/* work out how many numbers we want to generate */
*count = howmany;
*numbers = malloc(*count * sizeof(int));
/* fill *numbers array here */
return 0; /* success */
}
void caller(void)
{
int *numbers;
int count;
if (0 == make_numbers(&numbers, &count)) {
/* use the numbers */
free(numbers);
}
}
Upvotes: 2
Reputation: 106390
Technically speaking, a function only returns one value. Otherwise, it wouldn't be a function (remember mathematical functions? Same principle here.).
What you can do is:
Example involving arrays:
int* coords(int x, int y) {
int *a = calloc(sizeof(int), 2);
a[0] = x;
a[1] = y;
return a;
}
int main() {
int* vals = coords(47, -121);
printf("vals = {%d, %d}\n", vals[0], vals[1]);
return 0;
}
vals = {47, -121}
Upvotes: 1
Reputation: 109547
If you want no structs you can only pass by reference. Would need good documentation, maybe even declarative programming.
void compute(int& a, int& b, int& c) { ... }
void compute(int* a, int* b, int* c) { ... }
Upvotes: -1
Reputation: 9039
Not possible you have to pass pointers to variables and set them in your method. Like so:
void get_some_values()
{
int a=0, b=0, c=0;
compute(&a, &b, &c);
// after call to compute a=1, b=2, c=3;
}
void compute(int *a, int *b, int c*)
{
*a = 1;
*b = 2;
*c = 3;
}
Upvotes: 2
Reputation: 48280
If the values are all logically related, then it makes sense to put them into a structure. But if you're changing only a few values that aren't tightly coupled, you can pass them as pointers like this:
int swap(int *a, int *b) {
int tmp;
if (a == b) { // Pointers are equal, so there's nothing to do!
return -1; // Indicate the values haven't changed.
}
tmp = *a;
*a = *b;
*b = tmp;
return 0; // Indicate the swap was successful.
}
void main(...) {
int first = 12;
int second = 34;
if (swap(&first, &second) == -1) {
printf("Didn't swap: %d, %\n", first, second);
} else {
printf("Swapped: %d, %d\n", first, second);
}
}
It's a fairly standard technique to put data into the function arguments, and have the function return a value to indicate success/failure, or some other condition.\
Upvotes: 5