【问题标题】:How does switch case work when the cases have number prepended with 0?当案例的编号以 0 开头时,切换案例如何工作?
【发布时间】:2017-04-26 18:17:06
【问题描述】:

我正在开发 Ingenico 的 EDC 终端。以下代码存在于以前的实现中。在调试时,我遇到了我难以理解的这段代码。

short bankPEM = 0;
//bankPEM = 41; //Chip
bankPEM = 17; //Swipe
//bankPEM = 801; //Fallback

switch(bankPEM)
{
    case 021: cout<<"021"; break; //Swipe
    case 051: cout<<"051"; break; //Chip
    case 801: cout<<"801"; break; //Fallback
    default: cout<<"Default"; break;
}

bankPEM 是一个短变量。我发现下面的执行观察:

  1. 当它包含41时,case 051被执行。
  2. 当它包含17时,case 021被执行。
  3. 当它包含801时,case 801被执行。

我预计代码将执行 default 编号 1 和 2 的案例。 任何人都可以在这种情况下显示一些亮点。

我还将代码转换为汇编语言。调试完汇编代码后分享一下我的理解。

提前致谢。

【问题讨论】:

标签: c switch-statement


【解决方案1】:

参考c standard

6.4.4.1 整数常量

十进制常量以非零数字开头,由一串十进制数组成 位数。 八进制常量由前缀 0 可选地后跟一系列 仅限数字 0 到 7。 十六进制常量由前缀 0x 或 0X 组成 由一系列十进制数字和字母 a(或 A)到 f(或 F)的值 分别是 10 到 15。

强调我的

由于显示的代码似乎/是,您也可以参考c++14

2.13.2 整数字面量

整数字面量是没有句点或指数部分的数字序列,可选分隔单个 确定其值时忽略的引号。整数文字可能有一个前缀来指定它的基数 和一个指定其类型的后缀。数字序列的词汇第一个数字是最重要的。 二进制整数文字(以 2 为底)以 0b 或 0B 开头,由一系列二进制数字组成。 八进制 整数文字(以八为基数)以数字 0 开头,由一系列八进制数字组成。 十进制 整数文字(以 10 为基数)以 0 以外的数字开头,由一系列十进制数字组成。一个 十六进制整数文字(以十六进制为底)以 0x 或 0X 开头,由一系列十六进制组成 数字,包括十进制数字和带十进制值的字母 a 到 f 和 A​​ 到 F 十到十五。 [ 示例:数字 12 可以写为 12、014、0XC 或 0b1100。字面量 1048576、1'048'576、0X100000、0x10'0000 和 0'004'000'000 都具有相同的值。 —结束示例]

强调我的

【讨论】:

    【解决方案2】:

    021051这两个数字写在octal form中。如果将它们转换为十进制形式,您将得到:

    21 (base 8) = 1 * 8^0 + 2 * 8^1 = 1 + 16 = 17 (base 10)
    51 (base 8) = 1 * 8^0 + 5 * 8^2 = 1 + 40 = 41 (base 10)
    

    所以,我想你现在明白为什么当 bankPEM 为 17 时,case 021 被执行,而当它为 41 时,case 051 被执行。

    我不明白为什么实现代码的人决定编写这样的 switch 案例(甚至不一致,因为第 3 个案例的数字以 10 为底)。

    【讨论】:

      【解决方案3】:

      问题在零之前,如果声明在零之前,则编译器认为它是八进制数 021,因此 17 base 10 = 21 base 8 因此执行 case 021 :同样适用于 41 base 10 = 51 base 8。

       short bankPEM = 0;
      //bankPEM = 41; //Chip
      bankPEM = 17; //Swipe
      //bankPEM = 801; //Fallback
      
      
      
      switch (bankPEM) {
          case 021: cout << bankPEM << " " << 021;
      
              break; //Swipe
          case 051: cout  << bankPEM << " " << 051;
              break; //Chip
          case 801: cout << "801";
              break; //Fallback
          default: cout << "Default";
              break;
      }
      

      我希望这会有所帮助。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-04-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-05-12
        相关资源
        最近更新 更多