user14556999
user14556999

Reputation:

How to write a function which can return two integers?

(I was able to solve the previous problem with the output of the array, everything worked out).

I have here a piece of code for which I would like to write a function to shorten the code. But I don't know how to do it, since, apparently, it would need to return two values and I do not know how to do it...

Or should I break this action into two different functions?

Or it is better to leave the code in this form?

  int a2x = 0;
  int m2x = 0;
  for (i = 0; i < n; i++) {
    if (x[i] > 0) {
      a2x = a2x + x[i];
    }
    if (x[i] < 0) {
      m2x++;
    }
  }
  printf("\n");
  printf("a2x %5d \n", a2x);
  printf("m2x %5d \n", m2x);
  int a2y = 0, m2y = 0;
  for (j = 0; j < m; j++) {
    if (y[j] > 0) {
      a2y = a2y + y[j];
    }
    if (y[j] < 0) {
      m2y++;
    }
  }
  printf("a2y %5d \n", a2y);
  printf("m2y %5d \n",m2y);

Upvotes: 1

Views: 185

Answers (3)

There is technically a other way not mentioned before: Pass it in a larger integer type:

#include <limits.h>

#define HIGHEST_UINT_BIT ((UINT_MAX>>1)+1)
#define HIGHEST_ULLINT_BIT ((ULLONG_MAX>>1)+1)
#if HIGHEST_ULLINT_BIT/HIGHEST_UINT_BIT/HIGHEST_UINT_BIT<2
  #error "unsigned long long int not large enough to hold 2 int variables"
#endif

//returns the integer a in higher half of the returning long long int
//and the integer b in the lower half of the returning long long
unsigned long long int foo(void)
{
  int a=42;    //set a to any integer value you like
  int b=0x42;  //same for b

  //pack a and b into the return value
  //<<(sizeof(int)*CHAR_BIT) shifts a to the higher half of r
  unsigned long long int r=((unsigned long long)a)<<(sizeof(int)*CHAR_BIT);
  r|=(unsigned)b;

  return r;
}

#include <stdio.h>

int main(void)
{
  unsigned long long int r=foo();
  //extract a and b from r
  int a=r>>(sizeof(int)*CHAR_BIT);
  int b=r&UINT_MAX;

  printf("a is %i (0x%X) b is %i (0x%X)\n",a,(unsigned)a,b,(unsigned)b);
  return 0;
}

But you should never use this method. Because it is not scalable to more variables, it only works when there is a integer type which is 2 times as large or larger, it only works for integers and it is a hack. Better use the pass by pointer method mentioned in the other answers.

Upvotes: -1

anotherOne
anotherOne

Reputation: 1573

I propose you what I believe are the 3 easiest options you have:

I) Print the result inside the function.

In this way not only you don't need to return the variables, but you can also declare them directly inside the function.

II) Pass the variables by reference.

In this way the function can actually change their value, so you don't need to return anything.

III) Allocate an array storing the values that you want to return, and return the array.

In this way you can return as many values as you want.

Edit: As suggested by Andrew Henle in the comments to Yunnosch's answer: "returning a structure or passing the address of an array are likely all but identical performance-wise so at that point it's a style/preference/clarity/O&M issue which makes it very context-dependent."

And since, as Yunnosch pointed out, with a structure you can give a different meaning to each element, using a structure is more appropriate in your case.

Upvotes: 1

Yunnosch
Yunnosch

Reputation: 26753

You can have the function with this return type:

struct ReturnType
{
    int a2y;
    int m2y;
};

This type reflects that it is a pair of values, not two instances of the same value. I.e. it is a X and an M, not two Xs and not two Ms. It also behaves like a copyable variable, like returning a single int.

Upvotes: 6

Related Questions