问题描述
是否真的需要像某些使用字符编码或二进制缓冲区的库中那样使用unsigned char
来保存二进制数据?要理解我的问题,请看下面的代码-
char c[5], d[5];
c[0] = 0xF0;
c[1] = 0xA4;
c[2] = 0xAD;
c[3] = 0xA2;
c[4] = '';
printf("%s
", c);
memcpy(d, c, 5);
printf("%s
", d);
printf's
和都正确输出,其中
f0 a4 ad a2
是Unicode码点U+24B62 ()
的十六进制编码。
Evenmemcpy
也正确复制了字符保留的位。
什么理由可能主张使用unsigned char
而不是plain char
?
在其他相关问题中突出显示unsigned char
,因为它是C规范保证没有填充的唯一(字节/最小)数据类型。但如上面的例子所示,输出似乎不受任何填充的影响。
我已经用VC++Express 2010和MinGW编译了上面的代码。尽管VC给出了警告
warning C4309: '=' : truncation of constant value
输出似乎没有反映这一点。
附注:这可以标记为Should a buffer of bytes be signed or unsigned char buffer?的可能副本,但我的意图不同。我想问的是,为什么似乎可以与char
一起工作的内容要键入unsigned char
?
更新:引用N3337,
Section 3.9 Types
鉴于上述事实,而且我最初的示例是在char
默认为signed char
的Intel机器上,我仍然不确定是否应该优先使用unsigned char
而不是char
。
还有别的事吗?
推荐答案
在C中,unsigned char
数据类型是唯一同时具有以下三个属性的数据类型
如果这些是您要查找的"二进制"数据类型的属性,则您最终应该使用unsigned char
。
对于第二个属性,我们需要unsigned
类型。对于这些,所有的转换都是用模算法定义的,在大多数99%的体系结构中,这里的模UCHAR_MAX+1
,256
。因此,将较宽的值转换为unsigned char
仅对应于截断到最低有效字节。
其他两种字符类型通常工作方式不同。无论如何,signed char
是有符号的,所以不适合它的值的转换没有定义良好。char
不固定为已签名或未签名,但在您的代码移植到的特定平台上,它可能已签名,即使它在您的平台上未签名。