【问题标题】:Why is 'char' signed by default in C++?为什么在 C++ 中默认为“char”签名?
【发布时间】:2013-06-13 21:37:51
【问题描述】:

为什么 char 在默认情况下应该在 -128 到 127 的范围内表示一个“字符”,其文本表示在 0 到 255 的范围内?从这个意义上说,我猜 char 默认情况下应该是无符号的,只有当我们打算只将它视为“数字”时,我们才必须添加“有符号”关键字。因此,我在处理文本文件时应该使用 unsigned char 吗?

我也不明白为什么std::ofstream 的读写函数在我需要处理二进制文件时使用char 而不是unsigned char。我不在乎签名,是吗?此外,我已经成功地使用signed char 制作了一个 JPEG 文件的副本,如下所示:

//..open all streams..
char c;
while(input.peek()!=EOF){
    input.read(&c,1);   //std::ifstream input;
    output.write(&c,1); //std::ofstream output;
} 
//..close all streams..

由于它有效,我认为read 读取unsigned bytes(在图像处理中通常使用unsigned char)并设置c,以便该值在2 的补码中具有一些意外的符号解释。我需要创建一个值的直方图,但我得到一个运行时错误,因为我使用有符号字符作为索引。当 unsigned char 至少有一个简单的读/写重载时,我必须使用一些强制转换 uc = (unsigned char)c;?,这不是很愚蠢吗?

【问题讨论】:

  • char 并不总是签名的。 ASCII 以 127 结尾,因此考虑到几乎所有系统都使用它,因此不超过它是相当合乎逻辑的。
  • +1 @chris,它依赖于实现。
  • 哦,我显然错过了文档中关于 char 的注释。在我的电脑上,“char”是默认签名的,它的字符集包括一些重音字母,所以对我来说没有意义。
  • @DanielKatz 忘记“默认情况下”的术语。在 char 被签名的实现中,char 和 signed char 仍然是两种不同的类型。在 char 是 unsigned 的实现中,char 和 unsigned char 仍然是两种不同的类型。在all 实现中,char、signed char 和 unsigned char 始终是三种不同的类型。这与其他整数类型不同,其中术语“默认签名”是有意义的。
  • ASCII 以 127 结尾,但自相当古老的历史以来,我们在很多平台上都有 8 位字符 - ISO8859、Windows 代码页、DOS 代码页,所有那些 90 年代奇怪的 16 位机器和80 年代的 8 位机。当然 C 和 C++ 并没有说 char 是默认签名的,也许某些平台有理由默认首选签名 char,但我不明白为什么签名似乎总是默认的我用过的编译器。就好像编译器编写者天生就讨厌 8 位字符集。

标签: c++


【解决方案1】:

不是。

不是signed charunsigned charchar 的签名是实现定义的。许多系统将其签名以匹配默认情况下签名的其他类型(如int),但在某些系统上可能未签名。 (比如说,如果你将 -funsigned-char 传递给 GCC。)

【讨论】:

  • @DanielKatz:它是否在您的编译器上并不重要;它是实现定义的。你的定义是一种方式,另一个可以使用另一种方式。
  • std::cout << std::is_same<char, unsigned char>::value << "\n"; // false std::cout << std::is_same<char, signed char>::value << "\n"; // false
【解决方案2】:

这是您从标准中得到的答案:

3.9.1 基本类型 [basic.fundamental]

1 声明为字符 char) 的对象应足够大以存储实现的基本字符集的任何成员。如果该集合中的字符存储在字符对象中,则该字符对象的整数值等于该字符的单个字符文字形式的值。 char 对象是否可以保存负值是实现定义的。字符可以显式声明为无符号或有符号。普通字符、有符号字符和无符号字符是三种不同的类型。 char、signed char 和 unsigned char 占用相同的存储量并且具有相同的对齐要求(basic.types);也就是说,它们具有相同的对象表示。对于字符类型,对象表示的所有位都参与值表示。对于无符号字符类型,值表示的所有可能的位模式都表示数字。这些要求不适用于其他类型。 在任何特定的实现中,普通的 char 对象可以采用与有符号字符或无符号字符相同的值;哪一个是实现定义的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-11-02
    • 2011-01-03
    • 1970-01-01
    • 1970-01-01
    • 2013-05-25
    • 2011-09-17
    • 2011-01-20
    相关资源
    最近更新 更多