I love C. It's a whimsical language where anything's possible. In Java, the rules are very plain and boring and most whimsy is lost within some javadoc somewhere. C, on the other hand, you can abuse. And that's what we're doing today!
Most folks get a glimpse of the ternary conditional operator(?:) and never put it to much use. Well, if you design a program in a proper way (notice, in -A- proper way, not -THE- proper way), you can use it all the time instead of a plain, old, boring, readable
A review: Ternary means that it's n-ary where n = 3. In short, it a function that takes three inputs. Instead of saying, however, f(x,y,z), we say x?y:z. In C, x would be an int, where any non-zero value of x is considered true. y and z can have varying types depending on what you're trying to do. For instance, the single most common use of the ?: operator is assignment:
x = y == 1? 0 : 4;
Here, if y is equal to 1, x is assigned 0. Otherwise it's assigned 4. This kind of thing is in most textbooks. It's pretty boring, but useful. The operator can be nested, just like an "if" statement. This is also cool. So, if we have three integers, (a, b, and c) and wanted to assign a value to c based on a and b, we could do something like this:
c = a == 1 ? b == 1 ? 3 : 2 : 1;
The underlining is to show grouping. This is the same as:
SWEET, right? We turned nine lines of code (it'd be even more if you used Allman's indentation style where each brace gets its own line) into one single line.
"But, Mark! You said we could get rid of that nasty 'if' forever!" I said x and y could have different types, didn't I? Well, why not void? Notice that the ?: operator doesn't NEED to be used in assignment.
Becomes... you guessed it...
char m[5] = "mark"; !strcmp(m, "mark") ? printf("Hello, Mark!\n") : printf("You're not mark!\n");
Remember, strcmp returns 0 when strings are equal, so it "returns false" when they match.
Suppose we want to do multiple things in one code block, and, suppose there's no "else" statement? Here comes
We've got one assignment in there, and two regular function calls, right? We need a little superpower! Here's the magic secret on how this is gonna work: We need a void! "What?" Well, 'void' is a data-type, just like an int or a char, and it'll help balance this mess.
void x(); /* ← THE SUPERPOWER! */
a == 1 && b == 1? b = 1, one(b), two(), x : x;
What's the best part about this? Try compiling in GCC with -pedantic -std=c89
. That's right. It's perfectly legal. Also, if you throw the void around everywhere, you can nest as deeply as you like. One last example:
Notice, if there was an additional "else" with a "printf" inside, things would be easy, 'coz all the types would match. However, this isn't the case. We rely, again, on our good friend void.
void x(); !strcmp(c, "mark") ? printf("Hello, M4RK!\n"),x : !strcmp(c, "ange" ) ? printf("'Sup, ANG3LA!\n"), x : x;
That's all. Sadly, as I hinted in the introduction, this only works in C where most data types are really just integers in disguise. This kind of coding is very brief and easy to write, but it's much more useful in applications like the International Obfuscated C Code Contest.
Anyway, I hope this has been informative. You may return home.