【问题标题】:goto not working with ?: operator in Cgoto 不使用 ?: C 中的运算符
【发布时间】:2012-07-01 15:27:18
【问题描述】:

为了学习,我写了如下代码sn-p:

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 并不总是可以用?: 运算符替换感到困惑。这里的事实是什么?为什么注释的语句会报错?

【问题讨论】:

  • @Mat 你为什么用 V 编辑 c?
  • 对不起,错字。你有c,我想用C 替换,但滑倒了。顺便说一句,您可以编辑自己的帖子,您可以自己修复。
  • 我忘了。但是我点击了编辑然后我看到了 C,而不是 c……我保存了编辑……你还好吗 Mat??

标签: c goto conditional-operator


【解决方案1】:

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

goto 不是表达式,而是语句。

【讨论】:

    【解决方案2】:

    我对 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;
    

    【讨论】:

      【解决方案3】:

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

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

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

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

      【讨论】:

        【解决方案4】:

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

        【讨论】:

        • “goto found”是一个表达式吗?
        • @alaminhosain:他确实看到了标签。问题是表达式的结果是什么。例如,考虑:int p; p = (i==j &amp;&amp; i==3)? (goto found) : printf("stya here\n");。很明显pprintf 方面具有什么价值。但是pgoto 方面有价值吗?!这是编译器无法弄清楚的。
        • @Okay,那为什么这两个函数都无效(i==j &amp;&amp; i==3)? fun1() : fun2();
        • 如果你的函数被声明为void fun1(),它也不会工作。
        • @tristopia,在 c++ 中是否有任何修改,因为我刚刚看到在我的 Bloodshed/DevC++ 编译器中工作。
        【解决方案5】:

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

        以下是可能的:

        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
        

        【讨论】:

        • 为什么不呢,条件? dothis():printf("打印");作品?但是,条件? printf("print1") : printf("print2");有效吗?
        • 实际上,两者都应该工作,但老实说,在后一种情况下我更喜欢printf(condition ? "print1" : "print2");
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-07-28
        • 1970-01-01
        • 1970-01-01
        • 2011-12-29
        • 1970-01-01
        • 2016-06-01
        • 2021-10-13
        相关资源
        最近更新 更多