【问题标题】:How to determine the result of assigning multi-character char constant to a char variable?如何确定将多字符 char 常量分配给 char 变量的结果?
【发布时间】:2012-07-31 09:45:48
【问题描述】:

为什么一个char变量从'ab'的赋值得到'b',而不是'a'?

char c = 'ab';

printf("c: %c\n", c);

打印:

c: b

【问题讨论】:

    标签: c


    【解决方案1】:

    根据标准,它是实现定义的。来自6.4.4.4 字符常量

    整数字符常量的类型为 int。整数字符常量的值 包含映射到单字节执行字符的单个字符是 被解释为整数的映射字符表示的数值。 包含多个字符的整数字符常量的值(例如, 'ab'),或包含不映射到单字节的字符或转义序列 执行字符,由实现定义。

    【讨论】:

    • @ouah,怎么没有?它声明它分配给多字符文字的 int 值取决于实现。
    • @ouah 单个字符常量的值是多少并不重要,'b' 仍然表示为 'b'。这个答案确实回答了为什么是“b”而不是“a”的问题(即,这取决于实现),你的答案甚至没有触及。
    • @JimBalter 实际上,OP 编辑​​了他的问题以添加 而不是 'a' 恕我直言,这稍微改变了原始问题的意图。
    【解决方案2】:

    这是前面的答案已经说过的定义的实现。

    我的 gcc 将 'ab' 处理为 int。以下代码:

    printf( "sizeof('ab') = %zu \n", sizeof('ab') );
    printf( "'ab' = 0x%08x \n", 'ab' );
    printf( "'abc' = 0x%08x \n", 'abc' );
    

    打印:

    sizeof('ab') = 4
    'ab' = 0x00006162
    'abc' = 0x00616263
    

    在您的代码中,行:

    char c = 'ab';
    

    可以认为是:

    char c = (char)(0x00006162 & 0xFF);
    

    所以 c 获取 'ab' 的最后一个字符的值。在这种情况下,它是 'b' (0x62)。

    【讨论】:

      【解决方案3】:

      整数多字符常量的值是实现定义的,根据 C11 标准(§6.4.4.4 “字符常量”al10 p69):

      10 - [...] 包含多个字符的整数字符常量的值(例如, 'ab'),或包含不映射到单字节的字符或转义序列 执行字符,是实现定义的。 [...]

      【讨论】:

      • C90 和 C99 标准具有相同的规则。
      【解决方案4】:

      因为'ab' 的类型为int,而char 只能容纳一个字节。

      【讨论】:

      • 这没有回答问题,这就是为什么它得到'b'而不是'a',而不是为什么它得到'b'而不是'ab'。
      • @JimBalter 该问题已被编辑,在我回答时没有而不是'a'
      • P.S.由于这是一个 C 问题,'a''b' 也有类型 int
      • 抱歉,我没有注意到编辑。但请调整您的答案以适合当前问题。
      【解决方案5】:

      稍后编辑:我的回答与之前的回答相辅相成,非常清楚地表明这是特定于实现的行为。考虑到这一点,我的印象是OP想知道为什么编译器选择'b'而不是'a'。对不起,如果我的回答令人困惑。

      字节序。这就是为什么你得到'b'而不是'a'。 因为它在机器内存中的表示方式。 而且你的机器可能是小端的。

      在 sparc、mipsbe 或手臂上尝试一下,您可能会得到 'a' 而不是 'b'。

      无论如何,我希望您不要依赖于实际的生产代码。

      【讨论】:

      • 不只是字节序。甚至值本身的字符顺序也是未定义的。具有相同字节序的不同编译器使用不同的表示形式(例如 GCC 与 Visual Studio)。
      • 确实如此。但我认为这已经被之前的答案解决了。我只是想弄清楚为什么 OP 在他的测试中可能会得到 'b' 而不是 'a'。编译器可能会根据运行的平台选择表示和访问它的简单方法。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-02-25
      • 1970-01-01
      • 2016-08-19
      • 2011-09-05
      • 1970-01-01
      • 1970-01-01
      • 2013-12-11
      相关资源
      最近更新 更多