This question already has answers here:
What does the question mark character ('?') mean in C++?
(8 answers)
Closed 7 years ago.
Consider this function
template<class T> inline bool cx(T &a, T b) {return a < b ? a = b, 1 : 0;}
Can anyone explain what exactly this is doing? It seems different from the typical condition ? true : false format.
We could make it more clear like so:
return a < b ? (a = b, 1) : 0;
The parenthesized bit means "assign b to a, then use 1 as our value".
Comma-separated lists of values in C and C++ generally mean "evaluate all of these, but use the last one as the expression's value".
This combination is a little tricky, because it combines a comma operator with the conditional expression. It parses as follows:
a < b is the condition,
a = b, 1 is the "when true" expression
0 is the "when false" expression
The result of the comma operator is its last component, i.e. 1. The goal of employing the comma operator in the first place is to cause the side effect of assigning b to a.
You can execute several expression using ,
In this case if a < b, then assign b to a and return 1. According C++ grammar:
conditional-expression:
logical-or-expression
| logical-or-expression ? expression : assignment-expression
where
expression:
assignment-expression
| expression , assignment-expression
assignment-expression:
conditional-expression
| logical-or-expression assignment-operator initializer-clause
| throw-expression
The , operator just evaluates all the expressions, left to right, and evaluates to the value of the rightmost expression.
Your code is the same as...
if (a < b)
{
a = b;
return 1;
}
else
{
return 0;
}
Read it as:
if ( a < b )
{
a = b;
return ( 1 );
}
else
{
return ( 0 );
}
a < b ? a = b, 1 : 0 is parsed as (a < b) ? (a = b, 1) : 0, a normal conditional operator. When a < b is true, a = b, 1 is evaluated by assigning b to a and then "returning" 1. The net effect of cx(a,b) is thus to assign the larger value to a and to return 1 if a changed, 0 otherwise.
Related
My professor is having us change her functions to work for her assignment on Binary Search Trees. I know that this line she has assigns myHeight to whatever value being compared that is greater, but I have no idea how it's actually doing that.
int maxH = (hL > hR) ? hL : hR;
I want to use this in the future since it can save time writing code, but to do that I need to understand the syntax first. Thanks guys
This is the so called "conditional operator" in c++. It works as follows:
the expression before the ? is evaluated and converted to bool,
if it evaluates to true, the second operand is evaluated (i.e. hL in your example),
otherwise, the third operand (hR in your example) is evaluated.
The result is assigned to maxH.
See here for more detail (go down to the section "Conditional operator").
This is known as the conditional operator in C++.
"The conditional operator is an operator used in C and C++ (as well as other languages, such as C#). The ?: operator returns one of two values depending on the result of an expression.
Syntax
(expression 1) ? expression 2 : expression 3
If expression 1 evaluates to true, then expression 2 is evaluated.
If expression 1 evaluates to false, then expression 3 is evaluated instead.
Examples
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
In this example, the expression a > b is evaluated. If it evaluates to true then a is returned. If it evaluates to false, b is returned. Therefore, the line MAX(4, 12); evaluates to 12.
You can use this to pick which value to assign to a variable:
int foo = (bar > bash) ? bar : bash;
In this example, either 'bar' or 'bash' is assigned to 'foo', depending on which is bigger.
Or even which variable to assign a value to:
((bar > bash) ? bar : bash) = foo;
Here, 'foo' is assigned to 'bar' or 'bash', again depending on which is bigger."
https://cplusplus.com/articles/1AUq5Di1/
Using your teacher's example:
int maxH = (hL > hR) ? hL : hR;
This is equivalent to "if hL is greater than hR, then assign the value of hL to maxH, otherwise assign the value of hR to maxH."
The expression condition ? v1 : v2 returns v1 if condition is true, v2 otherwise.
int maxH = (hL > hR) ? hL : hR;
is equivalent to
int maxH;
if(hL > hR) maxH = hL;
else maxH = hR;
It's the conditional/ternary operator. It is used as an alternative to short if..else statements. Its syntax is as follows:
condition ? exprIfTrue : exprIfFalse
The condition before the (?) is evaluated as a bool. If it is true, exprIfTrue is executed. If it is false, exprIfFalse is executed. The (:) acts as the separator between the two conditions.
In your case, the condition evaluates if hL is greater than hR and assigns hL to integer max if it is true, or it assigns hR to integer max if it is false.
Note: Besides false, other false expressions could be null, NaN, 0, empty string (""), and undefined.
I have recently noticed an strange valid C/C++ expression in GCC/Clang which I have never seen before. Here is the example in C++, but similar expression works in C too:
int main(){
int z = 5;
auto x = ({z > 3 ? 3 : 2;}); // <-- expression
std::cout << x;
}
What it does is somehow obvious, but I like to know what it is called. Since it does not worth in MSVC, I guess it is a non-standard extension. But is there anything that works for MSVC too? especially in C?
It's called statement expr, used in GCC. Your expression ({z > 3 ? 3 : 2;}) can be translated to
if (z > 3) {x = 3;} else {x = 2;}
From documentation:
A compound statement enclosed in parentheses may appear as an
expression in GNU C. This allows you to use loops, switches, and local
variables within an expression.
In other word, it provides the ability to put a compound statement in an expression position.
Related post :
Emulating GCC Statement Expressions
Use of ({ ... }) brackets in macros to swallow the semicolon
It is called conditional operator . Return will be depend on condition either condition is true or false.
But in this case:
auto x = ({z > 3 ? 3 : 2;}); // <-- expression
if Z is greater than 3 returns 3 otherwise 2.
Basic syntax : Expression1? expression2: expression3;
I have implemented shunting-yard algorithm to parse arithmetic string-expressions from infix to postfix-notation.
I now also want to parse expressions with relational operators and Ternary conditional. Considering C++ Operator Precedence i added those operators with the lowest precedence and right-associativity for ? and : and the second-lowest and left-associativity for > and <.
When i now parse an expression like: A>B?C:D (where A, B, C and D can be any valid arithmetic expression) i would expect: A B > C D : ?, but i get A B C D : ? <. When i use Parentheses to evaluate the Condition first (A>B)?C:D it works. A mixed expression like (1+2<3+4)?C:D gives me 1 2 + 3 4 + < C D : ? which seems also legit to me. (A<B)?5+6:C gives me A B < 5 6 : + ? which again is messed up. Again, (A<B)?(5+6):C would fix that.
As stated in the comments, evaluating conditions first and the proceed with the left arithmetic expression would also be fine. But i really did not stumble upon an algorithm for evaluating expressions with relational and ternary operators in my research yet. Any help, even if pointing out an algorithm would be very appreciated
Here is the implementation of shunting-yard:
QQueue<QString> ShuntingYard::infixToPostfixWithConditionals(const QString& expression)
{
QStack<QString> stack;
QQueue<QString> queue;
QString token;
QStringList tokens = splitExpression(expression);
Q_FOREACH(QString token, tokens)
{
if (isDefineOrNumber(token))
queue.enqueue(token);
if (isFunction(token))
stack.push(token);
if (isOperator(token))
{
while (!stack.isEmpty() && isOperator(stack.top()) && isLeftAssociativeOperator(token) && !hasHigherPrecedence(token, stack.top()))
queue.enqueue(stack.pop());
stack.push(token);
}
if (isLeftParenthese(token))
stack.push(token);
else if (isRightParenthese(token))
{
while (!isLeftParenthese(stack.top()))
{
if (stack.isEmpty())
break;
if (isOperator(stack.top()))
queue.enqueue(stack.pop());
}
stack.pop();
if (isFunction(stack.top()))
queue.enqueue(stack.pop());
}
}
while (!stack.isEmpty())
{
if (isLeftParenthese(stack.top()))
break;
queue.enqueue(stack.pop());
}
return queue;
}
EDIT: made code and description more concise for readabilility
Another EDIT: Treating ?: as left-associative gave me the expected output
Now, regarding this question about the associativity of ternary conditionals. If i input a<b?a:b?c:d i get a b < a b c d : ? : ?, where a < b will be evaluated first, which is correct, due to its higher precedence, but then b ? c : d will be evaluated first, which is the correct right-to-left order. Confusing.
The code in question is "? something : something_else". Usually in the code below you can put either I2C_SLAVE or I2C_SLAVE_FORCE. But this code does something else. How does it work and what exactly does it do?
if(ioctl(state.i2c_bus_address, force ? I2C_SLAVE_FORCE : I2C_SLAVE, add) < 0)
{
logger.fail("i2c select fail %d",add);
return -1;
}
It's called the ternary conditional operator. It's like an if, but inline. Here's the format
boolean ? result evaluated to if true : result evaluated to if false
Here's an example:
y = x>2 ? 12 : 5;
If x is greater than 2, y will be 12, otherwise y will be 5.
It's name is "conditional operator".
condition ? expression1 : expression2
If condition evaluates to true, then evaluate expression1, otherwise evaluate expression2.
Not sure if this is what you're after, but the statement ? if_true : if_false control flow is called the ternary operator.
The statement is evaluated. If it's true, the expression after the : is evaluated. Otherwise, the expression after the : is evaluated.
Strange question, but someone showed me this,
I was wondering can you use the not ! operator for int in C++? (its strange to me).
#include <iostream>
using namespace std;
int main()
{
int a=5, b=4, c=4, d;
d = !( a > b && b <= c) || a > c && !b;
cout << d;
system ("pause");
return 0;
}
Yes. For integral types, ! returns true if the operand is zero, and false otherwise.
So !b here just means b == 0.
This is a particular case where a value is converted to a bool. The !b can be viewed as !((bool)b) so the question is what is the "truthness" of b. In C++, arithmetic types, pointer types and enum can be converted to bool. When the value is 0 or null, the result is false, otherwise it is true (C++ ยง4.1.2).
Of course custom classes can even overload the operator! or operator<types can be convert to bool> to allow the !b for their classes. For instance, std::stream has overloaded the operator! and operator void* for checking the failbit, so that idioms like
while (std::cin >> x) { // <-- conversion to bool needed here
...
can be used.
(But your code !( a > b && b <= c) || a > c && !b is just cryptic.)
Originally, in C (on which C++ is based) there was no Boolean type. Instead, the value "true" was assigned to any non-zero value and the value "false" was assigned to anything which evaluates to zero. This behavior still exists in C++. So for an int x, the expressions !x means "x not true", which is "x not non-zero", i.e. it's true if x is zero.
You can, !b is equivalent to (b == 0).
The test for int is true for non-zero values and false for zero values, so not is just true for zero values and false for non-zero values.
The build-in ! operator converts its argument to bool. The standard specifies that there exists a conversion from any arithmetic type(int, char,.... float, double...) to bool. If the source value is 0 the result is true, otherwise it is false