How to use the Conditional (ternary) operator:

Pages: 12
Note: It has become apparent that what is known as the ternary operator in C is in fact called the "Conditional Operator" in C++. Thank you, Grey Wolf.

So I was reading some code and I saw something that I'd never seen before:
(x == y) ? a : b
I pried open my C book (K&R) to find out what it was. "Ternary Operator" it said.

Some people might not know how to use it, so I thought I'd write a simple explanation:

Basic Syntax:
The ternary operator (?:) is a very useful conditional expression used in C and C++. It's effects are similar to the if statement but with some major advantages.

The basic syntax of using the ternary operator is thus:
(condition) ? (if_true) : (if_false)
Which is basically the same as:
1
2
3
4
if (condition)
    if_true;
else
    if_false;


Therefore if "condition" is true, the second expression is executed ("if_true"), if not, the third is executed ("if_false").

Now take the following example:
1
2
3
4
5
6
7
if (a > b) {
    largest = a;
} else if (b > a) {
    largest = b;
} else /* a == b */ {
    std::cout << "Uh oh, they're the same!\n";
}

That requires 7 lines and is unsuitable for something like a MIN/MAX function:
1
2
#define MIN(a, b) ((a < b) ? a : b)
#define MAX(a, b) ((a > b) ? a : b) 

The above code can be used like this:
int largest = MAX(a, b);
and will correctly assign a or b to largest.

Instead of the lengthy and more annoying (in this case) if statement we can use the ternary operator:
largest = ((a > b) ? a : b);

The main fundamental difference is that the ternary operator is an expression whereas the if structure is a statement. A ternary operator expression's result can be assigned to a variable -- the results of an if statement cannot.

Obviously the only advantage really that the if statement has is that you can have multiple clauses, where as with the ternary operator you can have only two.

However, according to wikipedia:
A GNU extension to C allows the second operand to be omitted, and the first operand is implicitly used as the second as well:

a = x ? : y;

The expression is equivalent to

a = x ? x : y;

except that if x is an expression, it is evaluated only once. The difference is significant if evaluating the expression has side effects.


If you're still unsure, try running the following code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>

int main() {
    int a, b;
    a = b = 0;

    std::cout << "Enter a number: ";

    std::cin >> a;

    std::cout << "\nEnter a number: ";

    std::cin >> b;

    std::cout << "Largest: " << ((a > b) ? a : b) << "\nSmallest: " << ((a < b) ? a : b) << std::endl;

    return 0;
}


Output:

$ g++ "MIN MAX.cpp" -o mm
$ ./mm
Enter a number: 256

Enter a number: 652
Largest: 652
Smallest: 256

Note: Stuff in bold is my input.

Please feedback :)

Sources:
The C Programming Language -- Brian Kernighan and Dennis Ritchie
http://en.wikipedia.org/wiki/Conditional_operator

Edits:
1. Fixed error noted by kempofighter,
2. Fixed errors in MIN & MAX macro functions where a & b were declared as A & B;
3. Fixed missing bracket in MAX(a, b) macro.
Last edited on
Nice job! if the final example doesn't print the last statement for you replace the "\n" with a std::endl. In my run time environment, the last statement did not get flushed. In a small program like that I think that it is better to just use std::endl to make sure that the statement will get flushed otherwise it might not be displayed to the console in some environments.
Oh? I've never experienced that! Well, now I know :)

Fixed.

My only gripe is that you can't replace this:
1
2
3
4
5
6
7
8
9
10
11
12
void exec(std::string args, bool block) {
    pid_t pid = fork();  // This process executes a given program

    if (pid == -1) {
        error("fatal fork error", true);
        exit(1);
    } else if (pid == 0) { // This is the child process
        child(args);
    } else { // This is the parent process.
        parent(pid, block);
    }
}


with this:

1
2
3
4
void exec(std::string args, bool block) {
    pid_t pid = fork();  // This process executes a given program
    ((pid == -1) ? ((pid == 0) ? child(args) : parent(pid, block)) : error("fatal fork error", true));
}

Edit: Although I guess that'd be pretty hard to understand, and also, the compiler might think I was trying to have 4 clauses... Well, I was, but that's not the point...
Last edited on
Just to add an opinion to an otherwise factual article, there are two main benefits to using the ternary operator:

1) To condense what would be at least 4 lines of code (depending upon your coding standards) to 1. (Bad) example, but illustrates the point:
1
2
3
4
5
6
7
if( x < 0 )
   abs_x = -x;
else
  abs_x = x;

// becomes:
abs_x = x < 0 ? -x : x;


2) To increase maintainability by eliminating duplicate code. Contrived example:
1
2
3
4
5
6
7
if( x < 0 )
    some_function( -x, 1, 2, 3, a, b, c, z, "Hello World" );
else
    some_function( x, 1, 2, 3, a, b, c, z, "Hello World" );

// becomes:
some_function( x < 0 ? -x : x, 1, 2, 3, a, b, c, z, "Hello World" );


Note above there is now only one call to some_function() instead of two, eliminating
the duplicate parameter list.

Nesting ternary operators is not recommended, because even one level of nesting
makes the code very hard to understand:

 
some_val = x >= 0 ? x : ( y >= 0 ) ? y : z;



It's too bad I didn't see this previously, it relates well to a thread a couple days ago on why a particular use of the ternary operator wouldn't compile. (or conditional operator, if that's what you prefer).

One additional note regarding the differences between ?: and if(), as I mentioned in that thread, is that other control statements cannot be embedded in the ?: operator. It is an operator, and thus must follow all the restrictions placed on parameters to operators.

So, something like this is an invalid use of ?:
1
2
3
while(1){
	(a>b) ? break : a++ ;
}


Function calls can be made within the ?:, just as they can be made within expressions using other operators, with one interesting example.

The following code somevar = myFunc() is valid, so long as the value returned by myFunc can be assigned to somevar. This must hold true with ?: as well, but here is the interesting example. ?: can be used without an actual assignment, so the following code:
 
(a>b) ? modifyB(b) : modifyA(a);


is perfectly valid even if modifyB() and modifyA() are declared as void functions, since there is no assignment occurring. If that expression was getting assigned to some variable however, those two functions would have to return a compatible type.

And one minor nitpick that has no tangible affect on your article, the ternary operator is not an expression itself. It's an operator that can be used, by itself or in conjunction with other operators, to formulate expressions.
As a mnemonic device to help make reading less confusing I convert a?b:c to IF a THEN b ELSE c.
It's threads like this, that makes me think that a good TEST forum for articles before they are published is a good idea. Once all the bugs in the article have been sorted out, then the OP would
publish it it the Articles forum (read only, no replies, locked, only the OP would be allowed to write/update)
Last edited on
I was merely trying to be helpful.
What do you think is better; an article that is mostly correct and local, and easy to find; or someone having to search for an article that may or may not be correct?
At least this way, other members of the forum can make addendums and corrections such that the readers and writer(s) of an article can all learn from it? The way it is posted on this forum, where other, more experienced members can add more information? In this way the post can be improved and therefore benefits even the writer of the article.

I enjoy the fact that I can post mostly correct and helpful information and other people can add things and make it more correct. I would hate the idea that other people would think my article is "sacred" and that they can't correct me where I'm wrong -- that way, other people learn wrong things and I get it wrong aswell. The current way benefits reader and writer and as such is better.

I sincerely disagree with you there.
Last edited on
(read only, no replies, locked, only the OP would be allowed to write/update)


That's not a forum.
I understand what guestgulkan is getting at. While this is a forum, the article section really should just contain articles and not posts on corrections. It can be a bit confusing for a reader especially not knowing if the information was ever updated. The problem with forum article sections is that anyone can post. Quite often you'll find people that just learned something 1 hour ago posting an article on it which leads to revision after revision which really pisses me off. Quite honestly if you don't have experience with the specific subject matter, you sure as hell shouldn't be posting an article about it as a learning experience. On the other hand, locking the article so that only the OP could update it could be a huge problem, especially if the OP has no freaking clue about what they posted.
Yeah, although in theory it would be a good idea, we would still get idiots posting stuff and not knowing what they are doing.
To Chrisname:
I wasn't getting getting at what you had written or the subject matter.
I'm saying that saying that the way this particular section works produces articles that are basically a mish mash of the original article as written by the OP, comments, disagreements, etc.

It is incoherent.
I still disagree... I think the point of the articles section is as a quick reference to things not covered by the rest of the site, and a local hoard of articles. The information I posted wasn't inherently wrong, or I would not have posted it. The corrections that were suggested were more suggestions than corrections, and I showed that it was updated.
Note: It has become apparent that what is known as the ternary operator in C is in fact called the "Conditional Operator" in C++. Thank you, Grey Wolf.

So I was reading some code and I saw something that I'd never seen before:
(x == y) ? a : b
I pried open my C book (K&R) to find out what it was. "Ternary Operator" it said.

Some people might not know how to use it, so I thought I'd write a simple explanation:


Basically you confirmed what I was talking about. Prior to writing this article you knew nothing of the conditional/ternary operator. So why not write an article about it right? This is why the articles forum or its process is a problem. I don't know... it just bothers me.

Whether the books or professionals refer to it is the ternary or conditional operator, conditional operator is correct as ternary is referring to the number of operands the operator takes:

unary = 1
binary = 2
ternary = 3

Basic Syntax:
The ternary operator (?:) is a very useful conditional expression used in C and C++. It's effects are similar to the if statement but with some major advantages.


What major advantages are you referring to??
Prior to writing this article you knew nothing of the conditional/ternary operator

No, I wrote this article about a week after I found out what the ternary operator is. I got K&R a little while ago; in truth I had seen it used on the internet, read a little about it and then read it in K&R to check that I knew what it was properly. Then I thought I'd write an article about it.

What major advantages are you referring to??

I don't implicitly name any in the article, but advantages such as assignment (being able to assign the result to a variable, e.g. with the MIN/MAX macros) are what I was referring to.
Whether the books or professionals refer to it is the ternary or conditional operator, conditional operator is correct as ternary is referring to the number of operands the operator takes
The conditional operator is the only ternary operator so you can call it both ways without ambiguities

What major advantages are you referring to??
The if is useful when you need to execute blocks, the ?: when you need different values. The conditional operator has advantages in many cases ( eg. when returning a value from a function etc. - see http://cplusplus.com/forum/articles/14631/#msg72866 )
Last edited on
oTpreirnaatroyr
I think we should have a wiki in the articles section. :D
That's be pretty cool. The problem is that just about every website has a wiki now...
Last edited on
How is that a problem?
Pages: 12