Multiple return in C / C ++

9

Is it possible to return multiple values? For example:

umafuncao()
{
    int x = 1, y = 2;
    return x,y;
}

void main()
{
    int a, b;
    a, b = umafuncao();
}

I'm asking this question, because I built a code using this structure for a task and passed all the tests, but I find nothing saying that this is functional.

Follow the code:

int findMaxCrossingSubArray(TItem *Receita, int low, int mid, int high)
{
    int i, j, maxLeft, leftSum = -100000, maxRight, rightSum = -1000000;
    int sum = 0;
    for( i = mid; i >= low; i--)
    {
        sum = sum + Receita[i].Chave;
        if( sum > leftSum)
        {
            leftSum = sum;
            maxLeft = i;
        }
    }
    sum = 0;
    for(j = mid + 1; j <= high; j ++)
    {
        sum = sum + Receita[j].Chave;
        if(sum > rightSum)
        {
            rightSum = sum;
            maxRight = j;
        }
    }
return (maxLeft, maxRight, leftSum + rightSum);
}

int findMaxSubArray(TItem *Receita, int low, int high)
{
int mid;
int leftLow, leftHigh, leftSum;
int rightLow, rightHigh, rightSum;
int crossLow, crossHigh, crossSum;

if(high == low)
{
    return (low, high, Receita[low].Chave);
}
else
{
    mid = (low + high)/2;
    leftLow, leftHigh, leftSum = findMaxSubArray(Receita, low, mid);
    rightLow, rightHigh, rightSum = findMaxSubArray(Receita, mid+1, high);
    crossLow, crossHigh, crossSum = findMaxCrossingSubArray(Receita, low, mid, high);
    if((leftSum >= rightSum) && (leftSum >= crossSum))
        return (leftLow, leftHigh, leftSum);
    else if((rightSum >= leftSum) && (rightSum >= crossSum))
        return (rightLow, rightHigh, rightSum);
    else
        return (crossLow, crossHigh, crossSum);
    }
}

int main()
{
    TItem *Receita;
    int low = 0, ndias, *taxa, lucro;
    taxa = malloc(sizeof(int));

    ndias = Carrega(&Receita, taxa);

    //Aqui começa a lógica para calculo do lucro maximo:

    low, ndias, lucro = findMaxSubArray(Receita, low, ndias-1);
    printf("%d", lucro > 0 ? lucro : 0);
    Libera(&Receita);
    return 0;
}
    
asked by anonymous 03.11.2015 / 14:25

4 answers

9

Multiple return

Neither C nor C ++ allow you to return multiple values in the function.

The most common when you need to return more than one value would be to pass a parameter by reference, so you put a value in it within the function and when you exit it, that value will stay in the passed variable. This is usually used when the returned values have little relation or are using older techniques.

Another more modern possibility is to use a data structure that encapsulates all values. It might be some kind of collection, like the default C array, the Vector that obviously only work if the type is the same, but they do not give the code good semantics. It can be a struct or class , or a Tuple , the most common in these cases .

The tuple is advantageous when the data is related and heterogeneous, as in a class. Returning a class is used when this data has a larger semantics in the application and is probably used in other places. It's not worth creating a class just for this single multiple return.

Comma operator

But what you saw in the code presented is not a multiple return. The operator represented by the comma is the sequence operator . It will execute all the expressions separated by each comma, in order and the last expression will be responsible for the result of the whole sequence. Then in:

return (maxLeft, maxRight, leftSum + rightSum);

return will be the value of leftSum + rightSum . Do not ask me why you have the previous values. They will be discarded and have no function there. In this case, it does not make sense because they do not execute anything, they only get the value that will be discarded later.

    
03.11.2015 / 14:44
7

What you're using without realizing it is the obscure Operator Comma . This operator evaluates the expression on the left, discards its value, evaluates the one on the right, and returns its value. For example: 1, 2 has a value of 2. Then int x = 1, 2; is equivalent to int x = 2; . This seems meaningless, but if you have an expression of type int x = a(), b(); and the function has side effects (modify the state of the program), it will be different from int x = b();

In case you use the comma operator as lvalue (left side of an assignment), as in a, b = umafuncao(); the compiler is only allowing you because you are using C ++, which allows this tag C is unsuitable for this question).

Now regarding your solution, I do not recommend using a vector to return its values, as was suggested, because their values, although having the same data type, have different semantics . This is relevant because whoever receives your feedback will have to look at your code to find out what each position in your vector means. The most appropriate is to create a simple class that holds the values you want to return giving them the proper names (leftLow, leftHigh etc.). Contrary to what it may seem, no, such a class is not heavy because it is quite optimizable - it is practically saved as a sequence of the bits of its members.

    
03.11.2015 / 15:01
3

Hello you can make use of vectors for this.

  

Example

int * umafuncao()
{
    static int retorno[2];
    retorno[0] = 1;
    retorno[1] = 2;

    return retorno;
}

void main()
{
    int *callfunc;
    int a, b;
    callfunc = umafuncao();
    a = callfunc[0];
    b = callfunc[1];
}
  

Or make use of pointers ...

void umafuncao(int *a, int *b)
{
    //Altero o valor direto na posição da memoria da variavel.
    *a = 1;
    *b = 2;
}

void main()
{
    int a, b;
    umafuncao(&a, &b);
}
    
03.11.2015 / 14:31
2

C ++ 17 introduced us to the wonderful world of Structured Bindings.

/ p>

This new feature allows you to return a tuple (or an object that behaves like one), and use a small sugar syntax to fill multiple variables with the items of this object:

#include <iostream>
#include <tuple>

auto f() {
    return std::make_tuple(1, 2);
}

int main() {
    auto [a, b] = f(); // Aqui
    std::cout << '(' << a << ',' << b << ')';
}

View on coliru

This code snippet is equivalent to the following snippet, compiled in C ++ 11:

#include <iostream>
#include <tuple>

std::tuple<int, int> f() {
    return std::make_tuple(1, 2);
}

int main() {
    int a, b;
    std::tie(a, b) = f();
    std::cout << '(' << a << ',' << b << ')';
}

View on coliru

    
26.05.2018 / 21:23