代码之家  ›  专栏  ›  技术社区  ›  Johannes Schaub - litb

为什么C++流使用CHAR而不是无符号字符?

  •  49
  • Johannes Schaub - litb  · 技术社区  · 17 年前

    我一直想知道为什么C++标准库已经实例化了BasIC[i]流及其所有变体。 char 键入而不是 unsigned char 类型。 烧焦 意味着(取决于它是否有符号)对于get()之类的操作可以有溢出和下溢,这将导致相关变量的实现定义值。另一个例子是,当您想使用一个字节的 put 功能。

    有什么想法吗?


    注释 我还是不太相信。所以如果你知道确切的答案,你仍然可以发布它。

    4 回复  |  直到 13 年前
        1
  •  23
  •   Steve Jessop    17 年前

    可能我误解了这个问题,但是从未签名的字符到字符的转换不是未指定的,它是依赖于实现的(在C++标准中是4.7到3)。

    C++中1字节字符的类型是“char”,而不是“unChar char”。这给了实现在平台上做最好事情的更多自由(例如,标准主体可能认为存在有符号字节算术比无符号字节算术更快的CPU,尽管这是我的猜测)。此外,对于C的兼容性,从C++中删除这种存在性不确定性的结果是C;

    考虑到“char”类型存在,我认为通常的流使用它是有意义的,即使它的签名没有定义。也许你的问题得到了答案,“为什么C++没有定义char是无符号的?”

        2
  •  15
  •   Daniel Trebbien    13 年前

    我一直是这样理解的:目的 iostream 类是读取和/或写入一个字符流,如果您考虑它,它是仅由计算机使用字符编码表示的抽象实体。C++标准很费劲地避免对字符编码进行钉住,只说“声明为字符的对象”。 char 应该足够大,以存储实现的基本字符集的任何成员,因为它不需要强制“实现基本字符集”来定义C++语言; 哪一个 字符编码用于实现(编译器和STL实现),请注意 烧焦 对象在某些编码中表示单个字符。

    实现编写器可以选择一个八位字节编码,例如 ISO-8859-1 甚至是双八位字节编码,例如 UCS-2 . 没关系。只要一个 烧焦 对象“足够大,可以存储实现的基本字符集的任何成员”(请注意,这明确禁止 variable-length encodings ,然后实现甚至可以选择一种表示基本拉丁语的编码,这种方式与任何通用编码都不兼容!

    令人困惑的是 烧焦 , signed char unsigned char 类型在其名称中共享“char”,但必须记住 烧焦 不属于与 符号字符 无符号字符 . 符号字符 在有符号整数类型家族中:

    有四个 带符号整数类型 :“signed char”、“short int”、“int”和“long int”。

    无符号字符 在无符号整数类型家族中:

    对于每个有符号整数类型,都存在一个对应的(但不同的) 无符号整数类型 :“unsigned char”、“unsigned short int”、“unsigned int”和“unsigned long int,”…

    两者之间的一个相似之处 烧焦 , 符号字符 无符号字符 类型是“它们占用相同的存储量,并且具有相同的对齐要求”。这样,你就可以 reinterpret_cast char * unsigned char * 以确定执行字符集中字符的数值。

    要回答您的问题,STL使用的原因 烧焦 因为默认类型是因为标准流用于读取和/或写入字符流,用表示 烧焦 对象,而不是整数( 符号字符 无符号字符 )使用 烧焦 与数值相对应是一种分离关注点的方法。

        3
  •  4
  •   Judge Maygarden    16 年前

    char代表字符,unsigned char代表原始数据字节,signed char代表有符号数据。

    标准没有指定有符号字符还是无符号字符将用于char的实现-它是编译器特有的。它只指定“char”足以在您的系统中保存字符,就像那些日子的字符一样,也就是说,不使用unicode。

    对字符使用“char”是标准的方法。使用无符号char是一种黑客行为,尽管它将匹配编译器在大多数平台上对char的实现。

        4
  •  0
  •   Community Mohan Dere    8 年前

    我想 this 评论解释得很好。引述:

    有符号char和无符号char是算术的整数类型,就像int和无符号int一样。另一方面,char被明确地指定为“I/O”类型,它表示平台上一些不透明的、系统特定的基本数据单元。我会本着这种精神使用它们。