【问题标题】:char containing single character when assigning `ab`分配`ab`时包含单个字符的char
【发布时间】:2021-02-05 11:56:38
【问题描述】:

当我声明char ch = 'ab' 时,ch 只包含'b',为什么它不存储'a'?

#include <stdio.h>

int main()
{
  char ch = 'ab';
  printf("%c",ch);
  return 0;
}

这里涉及的实际过程是什么?

【问题讨论】:

  • char ch = 'ab'; 应该给出警告,例如 warning: multi-character character constantwarning: overflow in conversion from 'int' to 'char' 。不要这样做,这是您作为初学者不需要的特定于实现的东西。
  • 编译时启用所有警告(-Wall 使用 gcc 和 clang,但在您的环境中可能会有所不同)。
  • C11 6.4.4.4 p10:“包含多个字符(例如,'ab')的整数字符常量的值 [...] 是实现定义的。”显然,在您的实现中,'ab' 映射到 'b'
  • @pmg 他得到'b'的事实主要是由于将> 8位值截断为字符。
  • @Jabberwocky:这也是我对他的实现的猜测。我相信if ('ab' == ('a' * 256 + 'b')) puts("I'm right"); 在他的电脑上打印“我是对的”:) --- ideone.com/Vfxsun

标签: c char


【解决方案1】:

当使用单引号' 包含ab 字符串时,您创建了所谓的多字符常量。您的程序的行为是实现定义的,这意味着如果我有不同的编译器或操作系统,我可能会看到值 a,即使您看到值 b

这不是一个好的做法,编译器应该发出警告。 如果您没有看到警告,请尝试使用标志-Wall-Wextra 启用警告进行编译,如果使用gccclang

您可以阅读有关此here in another answer 的更多信息。

【讨论】:

    【解决方案2】:

    一个字符文字,例如'A',其类型为int,其值为'A',很可能是0x41(A 的ASCII 值)。 当字符文字中有超过 1 个字节时,例如 'ab',结果是实现定义的。请注意,当以 UTF-8 存储超过 1 个字节时,这同样适用于 Unicode 代码点,这意味着 ASCII 之外的每个代码点,例如 '✓' 是一个多字符常量。

    在我的系统上,它仍然是int 类型,每个字节都存储在这个int 的8 位中,您的系统上可能也是这种情况。 'ab' 产生值 0x6162,0x61 是 'a' 的值,0x62 是 'b' 的值。您将值 0x6162 分配给 8 位 char,当 charsigned 时创建 UB,所以不要这样做。在您的情况下,它将值的低 8 位存储在 char 中,就像使用 unsigned char 时一样。 (如果signed charcharchar 签名的系统上,请不要转发此行为。

    你可以测试'ab'的值:

    #include <stdio.h>
    
    int main(void)
    {
      unsigned ch = 'ab';
      printf("0x%04X\n",ch);
      return 0;
    }
    

    这会在我的系统上输出0x6162

    【讨论】:

      猜你喜欢
      • 2019-05-01
      • 1970-01-01
      • 2015-03-30
      • 2021-09-15
      • 2011-08-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多