字节缓冲区应该是char或unsigned char还是char缓冲区?C和C++之间有什么区别?
谢谢.
如果您打算存储任意二进制数据,则应使用unsigned char
.它是唯一保证C标准没有填充位的数据类型.每个其他数据类型可以在其对象表示中包含填充位(即包含对象的所有位的填充位,而不是仅包含确定值的位).填充位的状态未指定,不用于存储值.因此,如果你使用char
一些二进制数据读取,事情将被削减到char的值范围(通过仅解释值位),但可能仍然有一些位被忽略但仍然存在并被读取memcpy
.很像真正的struct对象中的填充位.unsigned char
保证类型不包含那些.接下来是5.2.4.2.1/2
(C99 TC2,n1124):
如果在表达式中使用char类型的对象的值被视为有符号整数,则其值
CHAR_MIN
应与其值相同SCHAR_MIN
且值的值CHAR_MAX
应与.的值相同SCHAR_MAX
.否则,值CHAR_MIN
应为0,其值CHAR_MAX
应与.的值相同UCHAR_MAX
.价值UCHAR_MAX
应相等2^CHAR_BIT ? 1
从最后一句话可以看出,任何填充位都没有空间.如果你使用char
缓冲区的类型,你也有溢出的问题:明确地将任何值分配给8
位数范围内的一个这样的元素- 所以你可能希望这样的赋值是正确的 - 但不在范围内a char
,这是CHAR_MIN
.. CHAR_MAX
,这样的转换溢出并导致实现定义的结果,包括信号的提升.
即使对于上述可能不会在实际实施中出现任何问题(将是一个非常实行质量差),你是最好的,从开始之初,这是使用权类型unsigned char
.
但是,对于字符串,选择的数据类型是char
字符串和打印函数可以理解的.使用signed char
这些目的看起来像一个错误的决定对我来说.
有关更多信息,请阅读this proposal
其中包含下一版C标准的修复程序,最终将不需要signed char
任何填充位.它已经纳入工作文件中.
字节缓冲区应该是char或unsigned char还是char缓冲区?C和C++之间有什么区别?
语言如何处理它的细微差别.一个巨大的如何约定的区别对待它.
char
= ASCII(或UTF-8,但签名在那里的方式)文本数据
unsigned char
=字节
signed char
=很少使用
并且有代码依赖于这种区别.就在一两个星期前,我遇到了一个错误,其中JPEG数据被破坏,因为它被传递到char*
我们的Base64编码功能的版本 - 它"帮助"替换了"字符串"中所有无效的UTF-8.改为BYTE
aka unsigned char
只是修复它所需要的.
这取决于.
如果缓冲区旨在保存文本,那么将它声明为一个数组可能是有意义的char
,让平台在默认情况下决定是签名还是无符号.例如,这将使您在将数据传入和传出实现的运行时库时遇到的麻烦最少.
如果缓冲区旨在保存二进制数据,那么它取决于您打算如何使用它.例如,如果二进制数据实际上是一个打包的数据样本数组,这些数据样本是带符号的8位定点ADC测量值,那么signed char
这将是最好的.
在大多数实际情况中,缓冲区只是一个缓冲区,并且您并不真正关心单个字节的类型,因为您在批量操作中填充了缓冲区,并且您将要将其传递给解析器来解释复杂的数据结构并做一些有用的事情.在这种情况下,以最简单的方式声明它.
如果它实际上是一个8位字节的缓冲区,而不是机器默认语言环境中的字符串,那么我会使用uint8_t
.并不是说有很多机器,其中char不是一个字节(或一个字节是八位字节),但是使''这是一个八位字节的缓冲区'而不是'这是一个字符串'的语句通常是有用的文档.
您应该使用char或unsigned char,但从不签名char.该标准在3.9/2中有以下内容
对于POD类型T的任何对象(基类子对象除外),无论对象是否保持类型T的有效值,组成对象的基础字节(1.7)都可以复制到char或unsigned数组中char.如果将char或unsigned char数组的内容复制回对象,则该对象随后应保持其原始值.