Ternary (conditional) operator in C

What is the need for a conditional statement? Functionally, it is redundant because it implements the if-else construct. If the conditional operator is more efficient than the equivalent if-else assignment, why can't the if-else be interpreted better by the compiler?

+41
c operators ternary-operator conditional-operator
Apr 17 '09 at 3:09
source share
15 answers

The ternary operator is syntactic and readable convenience, not a performance label. People are divided into the merits of this for conventions of varying complexity, but for short conditions it is useful to have a single-line expression.

Moreover, since this expression, as Charlie Martin wrote , it means that it can appear on the right side of the instruction in C. This is valuable for short.

+57
Apr 17 '09 at 3:10
source share

In C, the real usefulness of this is that it is an expression instead of an expression; that is, you can have this on the right side (RHS) of the application. This way you can write some things more briefly.

+146
Apr 17 '09 at 3:14
source share

Some of the other answers are given. But I am surprised that no one has mentioned that it can be used to ensure the correct const correct.

Something like that:

 const int n = (x != 0) ? 10 : 20; 

therefore, basically n is const , the initial value of which depends on the condition operator. The easiest option is to make n not a const , this will allow the usual if initialize it. But if you want it to be const , this cannot be done with the usual if . The best replacement you could make would be to use a helper function like this:

 int f(int x) { if(x != 0) { return 10; } else { return 20; } } const int n = f(x); 

but triple if the version is much more compact and perhaps more readable.

+70
Apr 17 '09 at 3:29
source share

This is important for obfuscating code, for example:

 Look-> See?! No :( Oh, well ); 
+32
Apr 17 '09 at 3:22
source share

Compactness and the ability to embed the if-then-else construct in an expression.

+11
Apr 17 '09 at 3:11
source share

There are many things in C that are not technically necessary, because they can be more or less easily implemented from the point of view of other things. Here is a partial list:

  • but
  • for
  • Functions
  • Structures

Imagine what your code would look like without them, and you can find your answer. The ternary operator is a form of "syntactic sugar" which, when used with care and skill, makes writing and understanding the code easier.

+10
Apr 17 '09 at 3:13
source share

Sometimes a triple operator is the best way to get the job done. In particular, when you want the result of a triple value to be an l-value.

This is not a good example, but I draw a space better. One thing is certian, it is not often when you really need to use ternar, although I still use it very little.

 const char* appTitle = amDebugging ? "DEBUG App 1.0" : "App v 1.0"; 

One thing I would warn about, although it builds tees together. They become a real problem while working:

 int myVal = aIsTrue ? aVal : bIsTrue ? bVal : cIsTrue ? cVal : dVal; 

EDIT : Here is a potentially best example. You can use the ternary operator to assign links and const values, where you would otherwise need to write a function to process it:

 int getMyValue() { if( myCondition ) return 42; else return 314; } const int myValue = getMyValue(); 

... can be:

 const int myValue = myCondition ? 42 : 314; 

Which is better is a controversial issue that I will choose not to discuss.

+9
Apr 17 '09 at 3:15
source share

The fact that the ternary operator is an expression and not an expression allows it to be used in macro expansions for macros similar to functions that are used as part of an expression. The constant may not have been part of the original C, but the macro pre-processor goes back.

In one place where I saw it, an array is used in which macros are used for access with a controlled border. The syntax for the reference being checked was something like aref(arrayname, type, index) , where arrayname was actually a pointer to a structure that included the boundaries of the array and an unsigned array of char for the data, the type was the actual data type, and the index was an index. Extending this was pretty hairy (and I'm not going to do this from memory), but he used some ternary operators to check the binding.

You cannot do this as a function call in C because of the need for polymorphism of the returned object. Thus, a macro was needed to perform type casting in an expression. In C ++, you can do this as a template overloaded function call (probably for the [] operator), but C does not have such functions.

Edit: here is an example that I talked about from an array of Berkeley CAD arrays (version glu 1.4). Documentation on using array_fetch:

 type array_fetch(type, array, position) typeof type; array_t *array; int position; 

Extract an element from an array. A runtime error occurs when trying to link outside the array. There is no type check that the value at this position actually refers to the type used when dereferencing an array.

and here is the macro definition of array_fetch (note the use of the ternary operator and the sequence operator to execute all subexpressions with the correct values ​​in the correct order as part of a single expression):

 #define array_fetch(type, a, i) \ (array_global_index = (i), \ (array_global_index >= (a)->num) ? array_abort((a),1) : 0,\ *((type *) ((a)->space + array_global_index * (a)->obj_size))) 

The extension for array_insert (which expands the array if necessary, like a C ++ vector) is even more hairy, including several nested ternary operators.

+8
May 01 '09 at
source share

Since no one has mentioned this yet, the only way to get smart printf statements is to use the ternary operator:

 printf("%d item%s", count, count > 1 ? "s\n" : "\n"); 

Warning. There are some differences in operator precedence when switching from C to C ++ and may be surprised at the subtle error (s) that arise from this.

+7
Apr 17 '09 at 4:58
source share

This is syntactic sugar and convenient shorthand for short if / else blocks containing only one statement. Functionally, both designs should be performed identically.

+4
Apr 17 '09 at 3:12
source share

A ternary operator can have better performance than normal, if else, it can be crucial for embedded applications, but optimizing the compiler can make this difference.

+3
Nov 17 '12 at 17:36
source share

In some programming languages, if-else is an expression and evaluates the value

 def correct = true; def answer = if (correct) "Yes" else "No"; 

so there is no need for conditional expression.

+1
Apr 08 '10 at 17:25
source share

trernary = simple if-else form. It is available mainly for readability.

0
Apr 17 '09 at 3:15
source share

as dwn said, performance was one of its advantages when complex processors grew, MSDN blog Non-classic processor behavior: how something can be faster than not doing it gives an example that clearly shows the difference between the ternary (conditional) operator and if / else.

enter the following code:

 #include <windows.h> #include <stdlib.h> #include <stdlib.h> #include <stdio.h> int array[10000]; int countthem(int boundary) { int count = 0; for (int i = 0; i < 10000; i++) { if (array[i] < boundary) count++; } return count; } int __cdecl wmain(int, wchar_t **) { for (int i = 0; i < 10000; i++) array[i] = rand() % 10; for (int boundary = 0; boundary <= 10; boundary++) { LARGE_INTEGER liStart, liEnd; QueryPerformanceCounter(&liStart); int count = 0; for (int iterations = 0; iterations < 100; iterations++) { count += countthem(boundary); } QueryPerformanceCounter(&liEnd); printf("count=%7d, time = %I64d\n", count, liEnd.QuadPart - liStart.QuadPart); } return 0; } 

the cost for different borders is very different and more strange (see source material). and if you change:

  if (array[i] < boundary) count++; 

to

  count += (array[i] < boundary) ? 1 : 0; 

The execution time is now independent of the limit value, since:

the optimizer was able to remove the branch from the ternary expression.

but on my Intel i5 cpu / windows 10 / vs2015 desktop, my test result is very different from the msdn blog.

when using debug mode if / else cost:

 count= 0, time = 6434 count= 100000, time = 7652 count= 200800, time = 10124 count= 300200, time = 12820 count= 403100, time = 15566 count= 497400, time = 16911 count= 602900, time = 15999 count= 700700, time = 12997 count= 797500, time = 11465 count= 902500, time = 7619 count=1000000, time = 6429 

and the cost of a triple operator:

 count= 0, time = 7045 count= 100000, time = 10194 count= 200800, time = 12080 count= 300200, time = 15007 count= 403100, time = 18519 count= 497400, time = 20957 count= 602900, time = 17851 count= 700700, time = 14593 count= 797500, time = 12390 count= 902500, time = 9283 count=1000000, time = 7020 

when using release mode if / else cost:

 count= 0, time = 7 count= 100000, time = 9 count= 200800, time = 9 count= 300200, time = 9 count= 403100, time = 9 count= 497400, time = 8 count= 602900, time = 7 count= 700700, time = 7 count= 797500, time = 10 count= 902500, time = 7 count=1000000, time = 7 

and the cost of a triple operator:

 count= 0, time = 16 count= 100000, time = 17 count= 200800, time = 18 count= 300200, time = 16 count= 403100, time = 22 count= 497400, time = 16 count= 602900, time = 16 count= 700700, time = 15 count= 797500, time = 15 count= 902500, time = 16 count=1000000, time = 16 

the ternary operator is slower than the if else statement on my machine!

therefore, according to various compiler optimization methods, the ternal and if / else operator can behave very strongly.

0
Apr 22 '17 at 15:40
source share

Same as

 if(0) do(); if(0) { do(); } 
-2
Oct 24 '09 at 17:56
source share



All Articles