1

出于学习目的,我编写了以下代码片段:

for(int i=0;i<10;i++)
{
  for(int j = 0;j<5;j++)        
  {
    //(i==j && i==3)? (goto found) : printf("stya here\n");        
    if(i==j && i==3){goto found;} else {printf("stay here\n");}
  }
}

found:
  printf("yes I am here");

但是我想知道当我发现内部循环中省略的语句没有给出错误时,现在我对 if-else 并不总是可以用?:运算符替换感到困惑。这里的事实是什么?为什么注释语句会出错?

4

5 回答 5

10

运算符?:不能替代. if它仅适用于表达式:condition ? expr1 : expr2其中两个子表达式expr1expr2是相同类型(然后整个表达式是相同类型)。

goto不是表达,是陈述。

于 2012-06-30T09:19:45.053 回答
3

我对 C 语言不够精通,无法解释为什么这在语法上不起作用,但在意图的意义上, ?: 三元运算符形式旨在作为条件表达式(产生结果),而不是作为控制流机制。使用 if 语句,您可以为变量选择一个值或更改应用程序的流程。例如

//Change flow

if(x ==0)
{
   //do this
} 
else
{
 //goto some label
} 

或者

//Change value
    if(x == 0)
    {
      y = 1;
    }
    else
    {
      y = 2;
    }

三元仅用于第二种情况,作为条件表达式,即

y = (x ==0) ? 1 :2;
于 2012-06-30T09:42:44.657 回答
2

实际上,如果您的编译器支持扩展Statement Expressions,您尝试使用 goto 和三元运算符执行的操作是可能的,顾名思义,此扩展允许您在表达式或子表达式中编写语句,就像这样:

(rand() % 2) ? ({goto lbl1;}) : ({goto lbl2;});

使用这些语句可能非常有用(主要用于优化宏),但通常会导致非常脏的代码,就像我给出的示例一样 :)

因此,为了补充其他答案,我会说在 C99/11 中没有扩展是不可能的,但最近的大多数编译器都支持一堆扩展,可以让你做非标准的很酷的事情。

于 2017-12-20T15:54:58.593 回答
1

“goto found”表达式的结果是什么?我不知道,编译器也不知道,所以?无法确定表达式的结果,因此出现错误。

于 2012-06-30T09:19:57.607 回答
1

一般来说,?:运算符不能替代经典的if() ... else() .... 如果两个运算符(和条件)都是值或返回值的表达式,则可以这样使用它。您不能将它们与goto,break或之类的语句一起使用continue

以下是可能的:

condition ? dothis() : dothat(); // there's no assignment, but it's still valid
var = condition ? dothis() : othervar;
condition ? (var=4, othervar=3) : (somevar = 1);

但是你不能包含任何不是表达式的东西(即没有任何价值或结果的东西):

condition ? continue : break; // statements letting the execution continue somewhere else
condition ? {var = 4; othervar = 3;} : dothat(); // trying to inline scopes/multiple exressions
var = condition ? while(var) {var--;} : 5; // similar, inlining a complete loop

可以完成最后这些示例,但它们需要您使用if()或函数体来调用:

if (condition) continue; else break;
condition ? (var = 4, var = 3) : dothat();
var = condition ? dotheloop(var) : 5; // ok, this could be 'var = condition ? 0 : 5;' but... example code
于 2012-06-30T09:30:33.737 回答