简体   繁体   中英

Conditional operator unary in C

Can anyone explain to me or tell me how to fix this coding issue i have with conditional operator

it seems to always skip the conditional operator and just print out the second option even when i change server to be 0 or 1

and it always prints out the second option SetB then SetA

why does this not work? it is some kind of semantic error? or logical error?

#include <stdio.h>
#include <limits.h>

int main(int argc, char *argv[]){

   int ch = -191;
   int x = UINT_MAX;
   int setA[5]={-1,-1,-1,-1,-1};
   int setB[5]={-2,-2,-2,-2,-2};
   int server = 1;
   int i=2;

   printf("%d %d\n",server==1?setA[i],setB[i]:setB[i],setA[i]);
   printf("%d %d\n",server==0?setA[i],setB[i]:setB[i],setA[i]);


  // printf("%u\n%u\n",ch,x);

}

The grammar for the ternary operator is: condition ? expression : expression

In your code the first expression is setA[i], setB[i] and the second expression is setB[i] . Due to the way the language grammar works, the final comma is an argument separator (not a part of the second expression ), so your code is equivalent to:

int a = (server == 1) ? setB[i] : setB[i];
printf("%d %d\n", a, setA[i]);

which of course is the same as:

printf("%d %d\n", setB[i], setA[i]);

so you always get the same result regardless of the condition.


If you are going to have many similar lines in a block of code, one possible solution is to set up some set aliases based on the current server:

// do this once:
int *set0, *set1;
if ( server == 1 )
    set0 = setA, set1 = setB;
else
    set0 = setB, set1 = setA;

// then use it like this    
printf("%d %d\n", set0[i], set1[i]);
server==1?setA[i],setB[i]:setB[i],setA[i]

Note the comma operator between the conditional operator, this expression doesn't result as you expected.

Instead, I suggest using an if statement. It's more clear and less error-prone.

if (server == 1)
{
    printf("%d %d\n", setA[i], setB[i]);
}
else
{
    printf("%d %d\n", setB[i], setA[i]);
}

The expression

server==1?setA[i],setB[i]:setB[i],setA[i]

is equivalent to:

(server==1? (setA[i],setB[i]) : setB[i]), setA[i])

which is equivalent to

(server==1? setB[i] : setB[i]), setA[i]

which is equivalent to

setB[i], setA[i]

But, that's not what you wanted. What you wanted was:

if ( server == 1 )
{
  printf("%d %d\n", setA[i], setB[i]);
}
else if ( server == 0 )
{
  printf("%d %d\n", setB[i], setA[i]);
}

You should use the ternary operator like this:

server == 1 ? printf("%d %d", setA[i], setB[i]):printf("%d %d", setB[i], setA[i]);

and similarly for second statement.

The way you use it:

if server == 1
then setA[i], setB[i] evaluates to setB[i] , because that is property of comma , operator in C, and only the last statement is executed.

ie

If server == 1
then

printf("%d %d\\n",server==1?setA[i],setB[i]:setB[i],setA[i]);

will be evaluated as (due to high precedence of ?: operator over , operator)

printf("%d %d\\n",(server==1?(setA[i],setB[i]):setB[i]),setA[i]);

which is

printf("%d %d\\n",setB[i], setA[i]);

and similarly

printf("%d %d\\n",server==0?setA[i],setB[i]:setB[i],setA[i]);

will be evaluated simply as

printf("%d %d\\n",(server==0?(setA[i],setB[i]):setB[i]),setA[i])

which is again

printf("%d %d\\n",setB[i],setA[i]);

You can parse similarly for server == 0 you will get same result.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM