Problem with ternary operator

Asked

Viewed 415 times

0

I have a problem with the ternary operator. I want to use it to make the code more elegant because it is simple. But it’s as if it doesn’t work because it doesn’t update the variable. The following example shows the problem:

#include <iostream>
using namespace std;
int main()
{
    int k=0;
    for(int i=0;i<10;i++){
        k= (i<5)? k++:k;
    }
    cout << k << endl;
    return 0;
}

What can it be? Because the result of the variable k is shown as 0.

  • 4

    If you want to assign the value to k, why is using the operator ++, auto increment? Do you know how this operator works? In my view, write if (i < 5) k++; would be much more readable than the ternary operator.

  • 1

    As it is not possible to know the final goal, what was asked has infinite possibilities. Follow one more to the collection: for(int i=0;i<10;i++) k = i > 4 ? 5 : i;. Now, depending on the scenario, the most elegant would be this: cout << 5 << endl;

  • To fix it, just change it k++ for ++k, but there are other ways to correct this assignment k=( i<5 ? k++ : k );. How about k=( i<5 ? k+1 : k );? Or k+=int( i<5 );? Or k+=( i<5 ? 1 : 0 );?

2 answers

6

That expression won’t do what you want:

k= (i<5)? k++:k;

That means the following:

Se i < 5, então:
    Avalia o k (que é zero).
    Incrementa o k, que será um.
    Atribui o valor avaliado ao k, ou seja, zero.
Senão
   Atribui k ao próprio k (não faz nada).

What you wanted is just this:

if (i < 5) k++;

No use forcing the use of the ternary operator where it does not serve. The ternary operator is very useful but is not silver bullet. It’s not just because the hammer is a sensational tool that it should be used to change a light bulb.

  • If you used the prefixed operator ++k in the ternary would obtain the same result, however, as you well said, it makes no sense to use ternary in this case.

2

Or if you want to use conditional operator even though the performance may be even worse:

k += i < 5 ? 1 : 0;

Or

k += i > 4 ? 5 : i; //ver comentário do Bacco acima

Or even with likely better performance and less susceptible to bug processor:

k += !((4 + (~i + 1)) & 0x80000000);

this may not work in certain situations, so it is not a generic solution for any case.

#include <iostream>
using namespace std;

int main() {
    int k = 0;
    for (int i = 0; i < 10; i++) {
        k += !((4 + (~i + 1)) & 0x80000000);
    }
    cout << k << endl;
}

Behold working in the ideone. And in the repl it.. Also put on the Github for future reference.

Or

k += !(i / 5); //ver comentário do Victor Stafuza abaixo

Just testing, but it’s likely to be more expensive, division is a complicated operation for the processor. It will be as fast or as fast if the compiler knows how to optimize well (it is common for him to try to avoid divisions).

  • 1

    I think that k += !(i / 5); would be simpler. Anyway, this would all be just to produce overshadowed code and much more complex than needed.

  • 1

    @Victorstafusa Yes, the comment of Bacco up there is the only "right" even ;) Something tells me that the division would be less efficient, unless the compiler optimizes.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.