真的有必要像某些使用字符编码或二进制缓冲区的库那样使用unsigned char来保存二进制数据吗?为了理解我的问题,请看一下下面的代码-

char c[5], d[5];
c[0] = 0xF0;
c[1] = 0xA4;
c[2] = 0xAD;
c[3] = 0xA2;
c[4] = '\0';

printf("%s\n", c);
memcpy(d, c, 5);
printf("%s\n", d);

printf's?都正确输出,其中f0 a4 ad a2是Unicode代码点U+24B62 (?)的十六进制编码.

甚至memcpy也正确地复制了字符所包含的位.

有什么理由可以支持使用unsigned char而不是plain char

在其他相关问题中,unsigned char被突出显示,因为它是由C规范保证没有填充的唯一(字节/最小)数据类型.但是,如上面的示例所示,输出似乎不受任何填充的影响.

我已经用VC++Express2010和MinGW编译了上面的代码.尽管VC给出了警告

warning C4309: '=' : truncation of constant value

输出似乎没有反映出这一点.

顺便说一句,这可能是Should a buffer of bytes be signed or unsigned char buffer?的复制品,但我的意图不同.我是在问,为什么一些似乎与char同样有效的东西应该输入unsigned char

Update:引用自N3337,

Section 3.9 Types

2对于任何对象(基类子对象除外)的

鉴于上述事实,以及我最初的例子是在英特尔机器上,char默认为signed char,我仍然不确定unsigned char是否应该优先于char.

还要别的吗?

推荐答案

在C中,unsigned char数据类型是唯一同时具有以下三个属性的数据类型

  • 它没有填充位,即所有存储位都对数据值有贡献
  • 从该类型的值开始的任何按位操作在转换回该类型时都不会产生溢出、trap 表示或未定义的行为
  • 它可以在不违反"别名规则"的情况下别名其他数据类型,也就是说,通过不同类型的指针访问相同的数据将保证看到所有修改

如果这些是您正在寻找的"二进制"数据类型的属性,那么您肯定应该使用unsigned char.

对于第二个属性,我们需要一个unsigned的类型.对于这些,所有的转换都是用模arihmetic定义的,在大多数99%的体系 struct 中,这里是模UCHAR_MAX+1256.因此,所有更宽值到unsigned char的转换只对应于对最低有效字节的截断.

其他两种角色类型通常不一样.无论如何,signed char是有符号的,所以不符合它的值的转换没有很好的定义.char不固定为有符号或无符号,但在代码移植到的特定平台上,它可能会被签名,即使它在您的平台上没有签名.

C++相关问答推荐

我编译了一个新的c程序,并收到以下错误

为什么I2C会发送错误的数据?

不会停在空格或换行符上的错误

Clang:如何强制运行时错误的崩溃/异常由于-fsanitize=undefined

在列表中插入Int指针(C)

在为hashmap创建加载器时,我的存储桶指向它自己

无法在OpenGL上绘制三角形

强制转换变量以在 struct 中蚕食

为 struct 中的数组动态分配内存时出错

处理EPOLL_WAIT中的接收数据和连接关闭信号

在C中包装两个数组?

如何使用唯一数字对整型进行分区

当b是无符号字符时,int a=(b<;<;2)>;>;2;和int a=b&;0x3F;之间有什么区别?

Tic-tac-toe:从文件加载存储

为什么我在C代码中得到一个不完整的类型?

如何在不读取整个字符串的情况下删除UTF8字符串的尾随空格以提高性能?

如何在MSVC中使用intSafe.h函数?

挥发性语义的形式化理解

根据输入/输出将 C 编译过程分为预处理、编译、汇编和链接步骤

clion.我无法理解 Clion 中发生的 scanf 错误