Matouš Kovář
Matouš Kovář

Reputation: 15

Using multiple instructions inside ternary operator in C

I am new to learning C and I would like to know if it is possible to launch more than one instruction inside ternary operator in C - for example:

int a = 5;
int b = 7;
int max;
int min;
max = (a>b) ? a, b = min :  b, a = min;   
printf("%d %d", min, max);

I want to sort those numbers and assign them to a variable max or min. Is it possible to tell the program that if a > b it will save a as maximum and assign b to minimum? Or do I have to do it using If function? I think the problem is in using the comma, but I don't know what should I use instead. The message I get is this:

warning: left operand of comma operator has no effect [-Wunused-value] int max = (a>b) ? (a, b = min) : (b, a = min);

Upvotes: 1

Views: 1429

Answers (5)

chqrlie
chqrlie

Reputation: 145277

The syntax of the conditional expression is:

conditional-expression:
      logical-OR-expression
      logical-OR-expression ? expression : conditional-expression

Therefore, you must use parentheses at least for the third operand because of operator precedence.

Furthermore, your assignments were incorrect.

Here is a modified version:

#include <stdio.h>

int main() {
    int a = 5;
    int b = 7;
    int max;
    int min;
    max = a > b ? min = b, a : (min = a, b);
    printf("%d %d\n", min, max);
    return 0;
}

Output: 5 7

To avoid compiler warnings, you could write:

    max = a > b ? ((void)(min = b), a) : ((void)(min = a), b);

Note however that this method is very unusual, confusing and error prone. Use the ternary operator to perform just one computation at a time:

    int max = (a > b) ? a : b;  // max could even be declared as const int max = ...
    int min = (a > b) ? b : a;  // same for min

or just use an if statement:

    if (a > b) {
        max = a;
        min = b;
    } else {
        max = b;
        min = a;
    }

C is very versatile... Not every possibility is to be used and abused. Here are some more convoluted ones to avoid:

    // recursive
    *(a > (*(a > b ? &min : &max) = b) ? &max : &min) = a;
    // symmetric
    (min = a) < (max = b) || (max = a) > (min = b);
    // compact
    (min = max = a) > b ? (min = b) : (max = b);

Upvotes: 1

Fe2O3
Fe2O3

Reputation: 8364

Don't abuse the conditional operator. Doing so only makes code cryptic.

Instead, you can use C's innate values of 1 (true) and 0 (false.)

This code looks a bit more complex because it has 3 test cases. Apart from the tiny array pair, it is directly translatable to your simpler code.

int main() {
    int test[][2] = { { 5, 7 }, { 5, 5 }, { 5, 3 }, };

    for( int i = 0; i < sizeof test/sizeof test[0]; i++ ) {

        // two assignments, just like "int a = 5; int b = 7;"
        int pair[2] = { test[i][0], test[i][1] };

        // a conditional (stored for use)
        int max = ( pair[0] < pair[1] );

        // a print statement
        printf( "%d %d\n", pair[!max], pair[max] );
    }

    return 0;
}
5 7
5 5
3 5

Think about reading your code in 6 months or 6 years. "What was I thinking???"

Upvotes: 0

ZwergofPhoenix
ZwergofPhoenix

Reputation: 151

Does this not work?

(a < b) ? {min = a; max = b;} : {min = b; max = a;}

It's not beautiful, but usually you can use an execution scope as an expression argument, works for switch-case, I see no reason why it would not work here.

Upvotes: 0

Vlad from Moscow
Vlad from Moscow

Reputation: 311088

The conditional operator in C is defined the following way

conditional-expression:
    logical-OR-expression
    logical-OR-expression ? expression : conditional-expression

The assignment and the comma operator have lower precedence.

So this statement

max = (a>b) ? a, b = min :  b, a = min;

is equivalent to the following statement

max = ( (a>b) ? a, b = min :  b) , a = min;

Thus the variables max and b are set to the indeterminate value of the variable min if a is greater than b or to the value of the variable b otherwise. And then the variable a in turn is set to the indeterminate value of min.

It seems what you are trying to achieve is the following

max = a > b ? min = b, a :  ( min = a, b );

Though the code will be more readable if to split this statement into two statements like

max = a > b ? a : b;
min = a > b ? b : a;

Pay attention to that there is a difference between the definition of the compound operator in C and C++. In C++ the compound operator is defined like

conditional-expression:
    logical-or-expression
    logical-or-expression ? expression : assignment-expression

that is the third operand can be an assignment expression.

For example in C++ you may write

a < b ? max = b : max = a;

while in C this statement will look like

( a < b ? max = b : max ) = a;

and the compiler will issue an error message because the left operand of the assignment is rvalue instead of lvalue.

Upvotes: 2

Persixty
Persixty

Reputation: 8589

You've got your assignment (=) and the comma operator (,) backward. But as suggested in the comments this is obscure and unnecessarily difficult to read. Just write an if statement:

int a = 5;
int b = 7;
int max;
int min;

if(a>b){
    max=a;
    min=b;
}else{
    max=b;
    min=a;
}

It isn't bad practice to use the ternary operator but avoid using it to perform multiple actions like this. Don't treat it as some kind of inline alternative to if just because you can.

The advice for the comma operator (,) is more generally to avoid it. It's superfluous, error-prone and can be confused with the comma delimiter in function calls and declarations.

Upvotes: 4

Related Questions