2017-02-25 86 views
2

考虑下面包含重复情况的代码(C语言)。编译器这次没有提供任何警告/错误。数据类型和开关大小写语句解析

void testSwitchCase() { 
char d = 0; 
switch(d) { 
    case 'a' + 'b': 
     printf("I am case 'a' + 'b'\n"); 
     break; 
    case 'a' + 'b': 
     printf("I am case 'a' + 'b' \n"); 
     break; 
    } 
} 

但如果我改变char d = 0int d = 0,编译器开始提高公众对重复的情况下错误。

error: duplicate case value

我明白表达'a' + 'b'应评估到int但我的观点是,应该提高重复错误的情况下这两个时间。为什么它不?

+0

你使用什么编译器?你有没有试过在两个不同的编译器上运行这个? – Daniel

+0

gcc 32位。 codeblocks-16.01mingw其中包括GCC/G ++编译器。好的,让我试试一些在线编译器。 –

回答

6

此行为的原因是系统上的值为'a'+'b',在ASCII编码的系统上为195。这是高于127,最高char系统上的值与签署的个字符。因此,编译器安全地忽略了两个case标签。

由于值195int的范围内,编译器不能再忽略它,所以它必须发出重复的case错误。

如果更改'a'+'b''0'+'1',你97,这是一个符号字符的范围内,你会得到重复的情况下误差char d还有:

char d = 0; 
switch(d) { 
case '0' + '1': 
    printf("I am case 'a' + 'b'\n"); 
    break; 
case '0' + '1': 
    printf("I am case 'a' + 'b' \n"); 
    break; 
} 

Demo.

+0

是的错过了。现在明白了。谢谢 :) –

0

重复大小写错误表示您在switch语句中定义了两个具有相同值的情况。你可能正在考虑你的代码,“但它们都是不同的。”对你来说他们是不同的。对于编译器来说,它们看起来很不一样

您已经使用字符符号定义了case语句。单引号是用于字符,而不是字符串。

+3

我很确定OP知道这一切。看看他问题的最后一段。 – dasblinkenlight

+0

他想要角色。看看交换机中的表达式。而且他认为他们都是一样的,但是除非他将d变成一个整数,否则不会发出警告。 – Gerhardh

+0

你的误解与switch()结构无关,全部是关于单引号“':如果你写1,你得到一个整数值1,当你把它放在单引号'1'中时,你会得到数字1的ASCII字符的数字值(这有点不准确,请参阅下面的注释)。该ASCII字符的数值为0x31,即十进制中的49。现在想象一下不同。 – Siddhesh

1

时间太长并发布了7分钟太迟:P ...

我的猜测如下: char变量不能保存'a'+'b',这会导致se溢出,即未定义的行为。 但由于整数升级规则,'a'+'b'被提升为int。 char d永远不能等于这个值,编译器完全删除这些情况。 int d可以等于这两种情况并且编译器发出错误。