switch语句:必须默认是最后一种情况? [英] Switch statement: must default be the last case?

查看:146
本文介绍了switch语句:必须默认是最后一种情况?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑以下开关语句:

 开关(值)
{
  情况1:
    返回1;
  默认:
    价值++;
    //落空
  案例2:
    返回值* 2;
}

这code编译,但它是有效的(=定义的行为)的C90 / C99?我从来没有见过code,其中的默认的情况下,是不是最后一例。

编辑:结果
由于的乔恩·凯奇的和的 KillianDS 的写:这实在是丑陋和混乱code和我非常清楚这一点。我在通用语法(如何界定?)和预期产出只是有兴趣。


解决方案

C99标准不明确这一点,但把所有的事实一起,这是完全合法的。

A 情况默认标签相当于一个转到标签。见6.8.1标记语句。特别有趣的是6.8.1.4,它使已经提到的达夫设备


  

任何声明可能是由pceded $ P $
  preFIX声明的标识符
  标签名称。在自己做标签
  不改变控制流,它
  继续畅通碰到他们。


修改:一个开关内的code是没有什么特别的;这是code的正常块在如果语句来,额外跳标签。这解释了落空的行为,为什么是必要的。

6.8.4.2.7甚至举了一个例子:

 开关(表达式)
{
    INT I = 4;
    F(ⅰ);
情况下0:
    我= 17;
    / *落空违约code * /
默认:
    的printf(%d个\\ N,I);
}


  

在人工节目片段
  对象,其标识符是我的存在
  具有自动存储时间
  (块内),但决不
  初始化,并因此,如果
  控制前pression具有非零
  值,调用printf函数
  将进入一个不确定的值。
  类似地,调用函数f
  无法达成。


case常量必须是一个switch语句中是​​唯一的:


  

6.8.4.2.3每个案件标签的前pression应是一个整型常量
  前pression并没有两个案件
  在相同的恒定前pressions
  switch语句应具有相同的
  转换后的价值。可能有
  在交换机最多只有一个默认标签
  声明。


所有病例进行评估,然后跳转到默认的标签,如果给出:


  

6.8.4.2.5整数促销活动上进行控制
  前pression。恒恩pression在
  每种情况下的标签转化为
  推动型的控制
  前pression。如果转换后的值
  匹配推广的
  控制前pression,控制跳跃
  下列匹配的声明
  case标签。否则,如果有一个
  默认的标签,控制跳到
  标签的语句。如果没有转换
  案例不断前pression比赛,
  没有默认的标签,没有的一部分
  开关体被执行


Consider the following switch statement:

switch( value )
{
  case 1:
    return 1;
  default:
    value++;
    // fall-through
  case 2:
    return value * 2;
}

This code compiles, but is it valid (= defined behavior) for C90/C99? I have never seen code where the default case is not the last case.

EDIT:
As Jon Cage and KillianDS write: this is really ugly and confusing code and I am well aware of it. I am just interested in the general syntax (is it defined?) and the expected output.

解决方案

The C99 standard is not explicit about this, but taking all facts together, it is perfectly valid.

A case and default label are equivalent to a goto label. See 6.8.1 Labeled statements. Especially interesting is 6.8.1.4, which enables the already mentioned Duff's Device:

Any statement may be preceded by a prefix that declares an identifier as a label name. Labels in themselves do not alter the flow of control, which continues unimpeded across them.

Edit: The code within a switch is nothing special; it is a normal block of code as in an if-statement, with additional jump labels. This explains the fall-through behaviour and why break is necessary.

6.8.4.2.7 even gives an example:

switch (expr) 
{ 
    int i = 4; 
    f(i); 
case 0: 
    i=17; 
    /*falls through into default code */ 
default: 
    printf("%d\n", i); 
} 

In the artificial program fragment the object whose identifier is i exists with automatic storage duration (within the block) but is never initialized, and thus if the controlling expression has a nonzero value, the call to the printf function will access an indeterminate value. Similarly, the call to the function f cannot be reached.

The case constants must be unique within a switch statement:

6.8.4.2.3 The expression of each case label shall be an integer constant expression and no two of the case constant expressions in the same switch statement shall have the same value after conversion. There may be at most one default label in a switch statement.

All cases are evaluated, then it jumps to the default label, if given:

6.8.4.2.5 The integer promotions are performed on the controlling expression. The constant expression in each case label is converted to the promoted type of the controlling expression. If a converted value matches that of the promoted controlling expression, control jumps to the statement following the matched case label. Otherwise, if there is a default label, control jumps to the labeled statement. If no converted case constant expression matches and there is no default label, no part of the switch body is executed.

这篇关于switch语句:必须默认是最后一种情况?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆