为什么表达式的结果取决于表达式的放置位置?

Why does the result of an expression depend on where the expression is placed?

我目前正在开发一个更复杂的程序,我遇到了一个非常奇怪的语法错误,最好用以下最小示例来证明:

#include <iostream>

int main(int argc, char *argv[]){
        char c = 1 + '0';
        std::cout << 1 + '0' << std::endl;
        std::cout << c << std::endl;
        std::cout << '0' + 1 << std::endl;
        return 1;
}

此示例产生以下输出:

$ ./program
49
1
49

这里似乎发生的情况是,当从单个数字整数表达式到字符的转换发生在流语句之外时,它会成功,但是当它发生在这样的语句内部时,它会产生垃圾答案。

我试图在 Google 上找到其他人问类似的问题,但找不到任何相关内容。

我在 Ubuntu 16.04 LTS x64 上使用 g++ (Ubuntu 5.4.0-6ubuntu1~16.04.9) 5.4.0 20160609,但问题也出现在 clang version 3.8.0-2ubuntu4 (tags/RELEASE_380/final) 中,这排除了编译器错误。

int + char 的结果是 int。所以当你这样做时

char c = 1 + '0';

你居然得到了

char c = 49;

现在 c 的值为 49。但是,当您打印时,coutoperator << 超载以获取 char 而不是显示 49,而是显示 49 的字符代表.

当你这样做时

std::cout << 1 + '0' << std::endl;

因为 1 + '0' 是一个 int 你得到 operator <<int 重载,它只输出整数 49.


需要注意的是,在进行算术运算时,任何小于 int 的值都会被提升为 int。这意味着,char + charshort + shortchar + short、...都将是一个 int,所以即使是

std::cout << static_cast<char>(1) + '0' << std::endl;

仍然会给你一个整数输出。您必须将结果转换回 char 以获得 char 之类的

std::cout << static_cast<char>(1 + '0') << std::endl;

but when it happens inside such a statement, it produces a garbage answer.

没有

char c = 1 + '0';
std::cout << c << std::endl;

在这种情况下,右值 int 隐式转换为 char。然后 char 重载与 std::cout 一起使用,导致“1”作为 ASCII。


std::cout << 1 + '0' << std::endl;

在这种情况下,您要立即打印出整数,因此选择了整数重载,这将打印“1”的数值,即 49。