【问题标题】:C - Tricky Switch Case working .. !C-棘手的开关盒工作..!
【发布时间】:2011-04-25 07:32:53
【问题描述】:

伙计们,

最近开始学习C。
卡在一个点上。它关于 switch-case 语句的工作。

代码如下:

#include<stdio.h>

int main() {
        int i=4;
        switch(i) {

                default :       
                        printf("%s","Default");
                case 0:         
                        printf("%s","Case 0");
                case 1:         
                        printf("%s","Case 1");
                case 2:         
                        printf("%s","Case 2");

        return 0;
        }
 }  

我个人认为,应该打印“Default”,因为它与任何大小写值都不匹配。
但是当我在 Turbo C 中运行代码时,我观察到的是:

Default
Case 0
Case 1
Case 2  

在这里观察到同样的情况:http://www.ideone.com/pFh1d

有什么问题?这是编译器问题还是我的代码中有任何错误?


编辑:

PS:如果我必须先写默认情况,这有什么问题。有什么危害吗?

但是一旦编译器知道它必须执行默认语句,为什么我们需要在默认情况的语句之后放置一个break语句呢?

【问题讨论】:

  • 你的休息时间在哪里;声明?
  • 是否希望每个 case 语句都有一个中断?
  • 它不会执行匹配的case之后的所有case,直到它移出或找到break
  • 它不会“期待”任何东西。它做你要求它做的事情。使用break 它会做一件事,没有break 它会做另一件事。

标签: c switch-statement case-statement


【解决方案1】:

switch 语句将跳转到相应的casedefault,然后代码将继续执行到下一个break 语句。

由于您的代码没有break,它将从default: 开始,然后继续执行以下所有语句。在编写类似条件时,这有时可能是一个有用的技巧,但通常缺少 break 语句会导致混乱。

最后的 return 也位于错误的位置,它应该在 switch 语句之后。

修改如下。

        int i=4;
        switch(i) {

                default :       
                        printf("%s","Default");
                        break;
                case 0:         
                        printf("%s","Case 0");
                        break;
                case 1:         
                        printf("%s","Case 1");
                        break;
                case 2:         
                        printf("%s","Case 2");
                        break;

        }
        return 0;

【讨论】:

    【解决方案2】:

    但是一旦编译器知道它必须执行 default 语句,为什么我们需要在 default case 语句之后放置一个 break 语句呢?

    因为这就是语言的工作方式。该语言的标准规定应从匹配的 case-label 继续执行。您可能想知道为什么编译器不会在每个case 之后自动添加break 语句。好吧,如果是这样,我们将无法做到这一点:

    switch(x){
    case 1:
    case 2:
    case 3:
     // do something
     break;
    case 4:
     // do something else
     break;
    default:;
    }
    

    如果编译器在每个 case 之后都添加了一个break,我们就必须重写上面的代码如下:

      switch(x){
    case 1:
     // do something
    case 2:
     // do the same thing
    case 3:
     // do the same thing
    case 4:
     // do something else
    default:
    }
    

    【讨论】:

      【解决方案3】:

      它与defaule匹配,因此默认,然后由于break;不存在而执行所有案例

      按照以下方式进行以获得您的预期结果

       default :       
                              printf("%s","Default"); break;
                      case 0:         
                              printf("%s","Case 0");break;
                      case 1:         
                              printf("%s","Case 1");break;
                      case 2:         
                              printf("%s","Case 2");break;
      

      【讨论】:

      • 但是一旦编译器知道必须执行default语句,为什么还要在default case语句后面加上break语句呢?
      • @herbalessence 查看带有解释的 switch case 示例。 visualcplus.blogspot.com/2006/03/…
      • @Herbalessence - 如果你把它放在 最后,你就不必在 default 部分打断。这是最常见的放置位置。
      • @herbalessence:没有所谓的“默认声明”。 default: 标签是一个入口点。这是它唯一定义的东西:长复合语句的入口点。这只是一个点,与任何特定陈述无关。控件跳转到该点并从那里继续执行。 IE。 switch/case/default 构造只是goto 的一种形式。
      【解决方案4】:

      C 语言中switch 语句的主体是一个连续的复合语句,具有多个入口点。每个case/default 标签都是一个入口点。您可以在任何入口点输入该复合语句,它会一直执行到最后(当然,除非另一个跳转语句介入)。换句话说,switch 中的case 标签与goto 标签的工作方式相同。在这方面,default 标签与 case 标签没有任何不同。

      这正是您在实验中观察到的。 switch 中的语句如下所示

      {
        printf("%s","Default");
        printf("%s","Case 0");
        printf("%s","Case 1");
        printf("%s","Case 2");
        return 0;
      }
      

      您首先通过default: 标签输入此语句。由于您在进入switch 的主体后没有更改控制流(除了可能放错位置的最终return),所有四个printfs 都会更改为“fire”。

      以“但是一旦编译器知道它必须执行默认语句...”开头的问题的含义我不清楚。 C 中switch/case 构造的功能如上所述。这就是“编译器知道的”。另一方面,您似乎对switch/case 所做的事情有一些完全没有根据的自我发明的误解,并且出于某种原因期望编译器遵循相同的误解。我想说你需要读一本关于 C 语言基础的书,而不是试图猜测各种语言元素的作用。

      首先制作default 案例并没有错。考虑到我上面所说的,在某些情况下,语句中标签的顺序很重要。重要时,您必须根据自己的意图安排它们。如果您需要您的 default 案例成为第一个,请先做。如果你不需要它(或者它没有区别),你可以把它放在最后或者你想放的任何地方。

      【讨论】:

        【解决方案5】:

        根据标准,程序员必须在每个 case 之后手动放置 break,即使它是默认 case。 如果程序员没有放置中断,则意味着它将执行该案例及其以下的所有案例。 标准将这种类型的开关编程称为开关内的 FALL THROUGH 条件。

        【讨论】:

          猜你喜欢
          • 2017-09-27
          • 1970-01-01
          • 1970-01-01
          • 2021-05-23
          • 1970-01-01
          • 1970-01-01
          • 2022-12-09
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多