问题
Why the ternary operator does not have blocks? In other words, why the following code does not work and reports error for {}
braces?
int main()
{
int i = 1;
(i==1)?{printf("Hello\n")}:{printf("World\n")};
return 0;
}
EDIT
Perhaps the question is misunderstood. It was: why blocks are not supported? Why only single expression?
Why this is not allowed to work?
int main()
{
int i = 1;
(i==1)?{printf("Hello\n");printf("World\n");}:{printf("Bye\n");printf("World\n");};
return 0;
}
One reason could be that ternary are often used for conditional assignment on left side and blocks will have no such returns or it will get confusing with multiple statements inside block.
回答1:
To quote C11
standard, chapter §6.5.15, the syntax of the conditional operator is
conditional-expression:
logical-OR-expression
logical-OR-expression ? expression : conditional-expression
Where, the second and third operands are expression
, not statements.
Just to elaborate,
One of the following shall hold for the second and third operands:
— both operands have arithmetic type;
— both operands have the same structure or union type;
— both operands have void type;
— both operands are pointers to qualified or unqualified versions of compatible types;
— one operand is a pointer and the other is a null pointer constant; or
— one operand is a pointer to an object type and the other is a pointer to a qualified or unqualified version of void.
Edit:
To answer the question
Why only single expression?
again, quoting the standard,
....the result is the value of the second or third operand (whichever is evaluated), converted to the type described below.
Block of statements, will not give a value. The evaluation of an expression
can.
回答2:
The ternary operator consists of expressions. There is no such a kind of expression that uses braces.
You can write simply
( i == 1 ) ? printf("Hello\n") : printf("World\n");
It semss that the only case when braces can be present in an expression is the use of a compound literal. For example
struct A { int x; int y; } a = { 1, 2 };
a = a.x < a.y ? ( struct A ){ a.y, a.x } : ( struct A ){ ++a.x, --a.y };
As for this statement
(i==1)?{printf("Hello\n");printf("World\n");}:{printf("Bye\n");printf("World\n");};
then it can be rewritten the following way using the comma operator
i == 1 ? ( printf("Hello\n"), printf("World\n") ) : ( printf("Bye\n"), printf("World\n") );
Or even like
i == 1 ? printf("Hello\n"), printf("World\n") : ( printf("Bye\n"), printf("World\n") );
Shortly answering your question if you need a code block then use the if-else
statement instead of the ternary operator. Though the if-else
statement may not be used in expressions. On the other hand it is desirable for readeability of the code that expressions would not be too compound.
As any operator the ternary operator is used in expressions and returns some evaluated value. For example as an expression it can be used as initializer or in assignments.
回答3:
The ternary operator expects an expression for each part, and {...}
is not an expression, but a statement.
To expand on your edit, the result of a ternary operator is an expression (but not an lvalue as you suggest), and statement blocks can't evaluate to a value.
For example, this doesn't make sense:
int x = (i==1)?{printf("Hello\n");printf("World\n");}:{printf("Bye\n");printf("World\n");};
But you could do this:
int x = (i==1)?(printf("Hello\n"), printf("World\n")):(printf("Bye\n"), printf("World\n"));
In which case, the comma operator would cause the last value in each subexpression to be returned.
回答4:
Operators in C language can only be used in expressions. There's no such thing as "block" in an expression. In C language blocks are elements of higher-level syntactic structure. Blocks exists at the level of statements. Expression can be used in a statement. But statement cannot become an expression (or be used inside an expression).
Your particular example can be rewritten in terms of expressions
i == 1 ?
printf("Hello\n"), printf("World\n") :
printf("Bye\n"), printf("World\n");
without any need for {}
.
(See Uses of C comma operator for extra information)
回答5:
Yes only one expression is possible in ternary operators..You have to use if-else
for multiple statements. Ternary operators takes one expression only in each slot
although you can call two different functions in ternary operator
#include <stdio.h>
void a(){
printf("Hello\n");
printf("Hi\n");
}
void b(){
printf("Hi\n");
printf("Hello\n");
}
int main()
{
int i = 1;
(i == 1) ? a() : b();
return 0;
}
回答6:
The ternary operator is not meant to be used as a control structure, meaning it's not meant to control execution of statements. It's simply a way to choose which of two or more expressions will be evaluated.
As Sourav Ghosh has shown, the syntax of a conditional expression simply does not allow the operands of the ?:
operator to be statements.
回答7:
This is not allowed because it makes no sense. The ternary operator is meant to return a value. What would that be for {}
blocks?
And then also there is another construct if () { } else { }
that already serves the same purpose that you are trying to give to ? :
. Doesn't this here look much nicer than the code that you posted?
int main(void)
{
int i = 1;
if (i==1) {
printf("Hello\n");
printf("World\n");
} else {
printf("Bye\n");
printf("World\n");
};
return 0;
}
回答8:
As others have noted, GCC allows statements to be used syntactically as expressions, but such a feature is not part of the C standard. Historically, the reason for this likely had to do with the fact that statements are allowed to declare variables, and many systems use the same stack to hold local variables and parameters as is used to hold temporary values used in expression evaluation. Allowing new variables to come into existence within the execution of a statement while still keeping old variables in view would add some complexity to the compiler [note that when a function is called within a new expression, new variables are created for that function, but the old values will be "out of view" until the called function returns and the new variables are destroyed].
That having been said, other features of C such as variable-length arrays require far more complexity than would the ability to embed statements in expressions, so the arguments in favor of that design are no longer as compelling as they were in the 1970s. Unfortunately, the fact that something was once a compelling reason not to include a feature in a language may cause it to forevermore be perceived that way, even if design considerations for today's compilers are nothing like those of the 1970s.
来源:https://stackoverflow.com/questions/31300738/why-ternary-operator-does-not-support-blocks