【问题标题】:Difference between switch and while increment and evaluateswitch 和 while 增量和评估之间的区别
【发布时间】:2018-11-11 06:25:55
【问题描述】:

如果i等于1,则在此语句之后,

while (i++ <= 10){} 

i 被视为 2,即在块中评估之前递增。

但是如果用在switch中,

switch(i++){} 

i 在块中递增之前被评估。

为什么i++ 的这些案例表现不同?

例子:

对于 While 情况:

#include <stdio.h>

int main()
{
    int age = 20;

    while (age++ <= 65)
    {
        if ((age % 20) == 0)
        {
            printf("You are %d years old\n", age);
        }       
    }

    return 0;
}

我希望这会打印出来:

You are 20 years old
You are 40 years old
You are 60 years old

对于开关盒:

#include <stdio.h>

int main()
{
 int i = 0;

 while (i < 3)
 {
     switch (i++)
     {
         case 0:printf("print 0");
         case 1:printf("print 1");
         case 2:printf("print 2");
         default:printf("Oh no!");
     }
     putchar('\n');
 }

 return 0;
}

【问题讨论】:

  • 怎么样?我不明白。
  • 这两种情况应该是一样的。请出示minimal reproducible example 并解释您认为结果应该是什么,以及您看到的不同之处。
  • @Barmar 我在主帖下为这两种情况添加了示例。
  • 将代码放在问题中,而不是在远程站点。
  • 注意:您所有的案例标签都缺少break

标签: c while-loop switch-statement post-increment


【解决方案1】:

有了这个

while (i++ <= 10){} 

会发生以下情况:

  • i 从 1 开始
  • i(为一)与 10 进行比较
  • i 增加到 2
  • 块被执行,i 为 2

有趣的是,如果 i 从 10 开始,while 循环将再次执行,i 为 11。

有了这个:

switch(i++){}
  • i 从 1 开始
  • 根据“1”选择要执行的case
  • i 增加到 2
  • 执行“1”的情况,i 为“2”

【讨论】:

    【解决方案2】:

    事实上,在这两种情况下都发生了相同的情况:原始值用于比较,它被递增并且块被执行。看下面的代码:

    #include <stdio.h>
    
    int main() {
        int i=1;
    
        switch(i++) {
        case 1:
            printf("Case 1: %d\n", i);
            break;
        default:
            printf("Not 1: %d\n", i);
        }
        return 0;
    }
    

    它的输出是:

    Case 1: 2
    

    这证明i 在评估块之前被递增了。

    【讨论】:

      【解决方案3】:

      不,不可能。

      在这两种情况下,值的递增,后递增运算符的副作用发生在结果的值计算之后。

      引用C11,第 §6.5.2.4 章,(强调我的

      后缀++运算符的结果是操作数的值。作为一个副作用, 操作数对象的值递增(即相应类型的值 1 为 添加到它)。[...] 结果的值计算在副作用之前排序 更新操作数的存储值。 [...]

      详细说明

      • while (i++ &lt;= 10)的情况下,i的值在增量之前用于验证循环条件。

      • switch(i++){} 的情况下,i 的值在递增之前用于跳转到特定情况。未修改(尚未)的值用作控制表达式的值,在对控制表达式求值后进行递增。

      要补充的是,如果您尝试在其中一个 case 语句(例如,case 1:)中打印 i 的值,您可以看到它实际上增加了。

      【讨论】:

      • 我在主帖下添加了两个例子。
      • @Lyrk 阅读我回答的最后一部分。
      • 在while情况下,increment(1)之前的i值仅用于验证,但在while块中,i的增量值(2)用于计算。在 switch 中,i 在 switch 块中使用增量值之前。我的意思是 1 在 switch 块中使用,而不是在 while 的情况下使用 2。这是为什么呢?
      • @Lyrk 你错了。是什么让您认为正在发生这种情况?
      • @Lyrk 我认为你被愚弄了,因为当你忽略 breakswitch 的失败行为。
      【解决方案4】:

      while 循环不会打印You are 20 years old,因为变量在执行循环体之前递增。它以age = 20 开头。第一个

      while (age++ <= 65)
      

      测试是否20 &lt;= 65,因此进入循环。然后它递增age,所以在循环内它是age = 21。结果,测试if (age % 20 == 0) 不会成功,并且您不会收到You are 20 years old 的消息。

      20 的其他倍数仍会在循环的未来迭代中打印出来。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-02-01
        • 1970-01-01
        • 2013-04-10
        • 1970-01-01
        • 1970-01-01
        • 2014-11-07
        • 2013-11-02
        • 2010-10-03
        相关资源
        最近更新 更多