为什么C ++stream使用char而不是unsigned char?

我一直想知道为什么C ++标准库已经实例化了basic_ [io]stream及其所有使用chartypes而不是unsigned chartypes的变体。 char意味着(取决于它是否被签名),像get()这样的操作可能会产生上溢和下溢,这将导致所涉及variables的实现定义值。 另一个例子是当你想输出一个字节,无格式,使用它的put函数的ostream。

有任何想法吗?


注意 :我还没有真正相信。 所以如果你知道确切的答案,你仍然可以发布它的确。

可能我错误地理解了这个问题,但是从unsigned char到char的转换并不是未指定的,它是依赖于实现的(C ++标准中的4.7-3)。

C ++中1字节字符的types是“char”,而不是“unsigned char”。 这使得实现在平台上做最好的事情时有更多的自由(例如,标准组织可能认为存在有符号字节algorithm比无符号字节algorithm更快的CPU,虽然这是我的猜测)。 也是为了与C兼容。从C ++中去除这种存在的不确定性的结果是C#;-)

考虑到“char”types的存在,我认为即使未定义其签名,通常的stream也可以使用它。 所以也许你的问题被回答为“为什么C ++没有定义char被无符号?

我一直都这样理解: iostream类的目的是读取和/或写入一个字符stream,如果你考虑这个string,那么这个抽象的实体只能由计算机使用字符编码来表示。 C ++标准极力避免固定字符编码,只说“被声明为字符( char )的对象应该足够大,以存储实现的基本字符集的任何成员”,因为它不需要强制“实现基本字符集”来定义C ++语言; 标准可以决定使用哪种字符编码来实现(编译器和STL实现一起使用),只要注意char对象在某些编码中代表单个字符。

实现编写者可以select单字节编码,如ISO-8859-1 ,甚至可以select诸如UCS-2的双字节编码。 没关系。 只要char对象“足够大以存储实现的基本字符集的任何成员”(注意,这明确禁止可变长度编码 ),那么实现甚至可以select代表基本拉丁文的编码,与任何常见的编码不兼容!

charsigned charunsigned chartypes在它们的名字中共享“char”是令人困惑的,但要记住char不属于与signed charunsigned char相同的基本types族。 signed char是有符号整数types的家族:

有四个有符号整数types :“signed char”,“short int”,“int”和“long int”。

unsigned char是无符号整数types的家族:

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

charsigned charunsigned chartypes之间的相似之处在于“它们占用相同的存储量并具有相同的alignment要求”。 因此,你可以把unsigned char *中的reinterpret_cast改为unsigned char * ,以便确定执行字符集中一个字符的数字值。

为了回答你的问题,STL使用char作为默认types的原因是因为标准stream是用于读取和/或写入由char对象表示的charstream,而不是整数( signed charunsigned char )。 char与数字值的使用是分离问题的一种方式。

char用于字符,unsigned char用于数据的原始字节,signed字符用于签名数据。

Standard没有指定是否使用带符号或无符号字符来实现字符 – 它是编译器特定的。 它只是指定“字符”将“足够”,以保持您的系统上的字符 – 方式字符在那些日子,也就是没有UNICODE。

使用“字符”字符是标准的路要走。 使用无符号字符是一个黑客,虽然它将在大多数平台上匹配编译器的char的实现。

我觉得这个评论很好解释。 去引用:

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