Answers:
它记录了您的意图-您将存储少量数字,而不是字符。
如果您使用其他类型定义,例如uint16_t
或,它也会看起来更好int32_t
。
unsigned char
或signed char
记录意图,因为未经修饰的char
字符表明您正在使用字符。
unsigned
是unsigned int
通过定义?
char
似乎暗示着一个字符,而在UTF8字符串的上下文中,它可能只是多字节字符中的一个字节。使用uint8_t可以清楚地表明,不应在每个位置都期望有一个字符-换句话说,字符串/数组的每个元素都是一个任意整数,不应对其进行任何语义假设。当然,所有C程序员都知道这一点,但是它可能会促使初学者提出正确的问题。
只是为了讲究技巧,某些系统可能没有8位类型。根据维基百科:
当且仅当它具有满足要求的任何类型时,才需要实现为N = 8、16、32或64定义精确宽度整数类型。即使支持任何其他类型,也不需要为其他任何N定义它们。
因此uint8_t
不能保证存在,尽管它适用于8位= 1字节的所有平台。一些嵌入式平台可能有所不同,但是这种情况越来越少。一些系统可能将char
类型定义为16位,在这种情况下,可能不会有任何8位类型。
除了那个(次要的)问题,我认为@Mark Ransom的答案是最好的。使用最清楚显示数据用途的数据。
另外,我假设您的意思是uint8_t
(标stdint.h
头中提供的C99的标准typedef )而不是uint_8
(不是任何标准的一部分)。
uint8_t
(或对此类型进行typedef定义)。这是因为8位类型在存储表示中将有未使用的位,这些位uint8_t
必须没有。
typedef unsigned integer type uint8_t; // optional
因此,本质上,根本不需要C ++标准的兼容 库来定义uint8_t(请参阅注释// optional )
重点是编写与实现无关的代码。unsigned char
不保证是8位类型。uint8_t
是(如果有)。
sizeof(unsigned char)
将返回1
1个字节。但是,如果系统char和int的大小相同,例如16位,则sizeof(int)
也将返回1
如您所说,“ 几乎每个系统”。
char
可能是更改的可能性较小的一种,但是一旦您开始使用uint16_t
和朋友使用uint8_t
,就可以更好地使用混合,甚至可能成为编码标准的一部分。
根据我的经验,有两个地方我们想使用uint8_t表示8位(以及uint16_t等),并且我们可以将字段设置为小于8位。这两个地方都是空间重要的地方,我们经常需要在调试时查看数据的原始转储,并且需要能够快速确定数据的含义。
首先是在RF协议中,尤其是在窄带系统中。在这种环境下,我们可能需要将尽可能多的信息打包成一条消息。第二个是在闪存中,我们的空间可能非常有限(例如在嵌入式系统中)。在这两种情况下,我们都可以使用打包数据结构,其中编译器将为我们处理打包和拆包:
#pragma pack(1)
typedef struct {
uint8_t flag1:1;
uint8_t flag2:1;
padding1 reserved:6; /* not necessary but makes this struct more readable */
uint32_t sequence_no;
uint8_t data[8];
uint32_t crc32;
} s_mypacket __attribute__((packed));
#pragma pack()
使用哪种方法取决于编译器。您可能还需要使用相同的头文件来支持几种不同的编译器。这在设备和服务器可能完全不同的嵌入式系统中发生-例如,您可能具有与x86 Linux服务器通信的ARM设备。
使用打包结构有一些警告。最大的陷阱是您必须避免取消引用成员的地址。在具有多字节对齐字的系统上,这可能导致未对齐异常和核心转储。
有些人还会担心性能,并认为使用这些打包结构会降低系统速度。的确,在后台,编译器添加了代码以访问未对齐的数据成员。通过查看IDE中的汇编代码,您可以看到这一点。
但是,由于打包结构对于通信和数据存储最有用,因此当在内存中使用数据时,可以将数据提取为非打包表示形式。通常,我们无论如何都不需要处理内存中的整个数据包。
这里是一些相关的讨论:
pragma pack(1)或__attribute__((aligned(1)))都有效
gcc的__attribute __((packed))/ #pragma pack是否不安全?
http://solidsmoke.blogspot.ca/2010/07/woes-of-structure-packing-pragma-pack.html
没什么 从可移植性的角度来看,char
不能小于8位,并且不能小于8位,char
因此,如果给定的C实现具有无符号的8位整数类型,则它将为char
。或者,它可能根本没有,在这一点上没有任何typedef
技巧可言。
从某种意义上说,很显然您只需要8位字节,就可以用它来更好地记录代码。但是实际上,几乎在任何地方都已经是一个合理的期望了(在DSP平台上还不是这样,但是代码在那儿运行的机会很小,而且您也可以在程序顶部使用静态断言来出错)这样的平台)。
unsigned char
必须能够保持0到255之间的值。如果可以用4位来完成此操作,那么我就不高兴了。
uint8_t
到实现中。我想知道,具有16位字符的DSP的编译器是否通常实现uint8_t
?
#include <stdint.h>
并使用的最直接的方法uint8_t
。如果平台有它,它将提供给您。如果平台没有该程序,则您的程序将无法编译,其原因将是明确而直接的。
在几乎每个系统上,我都遇到过uint8_t == unsigned char,但是C标准不能保证这一点。如果您试图编写可移植的代码,而这与内存的大小完全相关,请使用uint8_t。否则,请使用unsigned char。
uint8_t
总是匹配 8位的范围和大小unsigned char
以及填充(无)unsigned char
。当unsigned char
不是8位时,uint8_t
不存在。
unsigned char
是8位,被uint8_t
保证是一个typedef
其而不是typedef
一个的延长的无符号整数类型?
unsigned char/signed char/char
最小的类型-不小于8位。 unsigned char
没有填充。由于uint8_t
必须提供整数类型,因此必须为8位,不存在填充,因为该类型符合的最低要求unsigned char
。至于“ ...保证是typedef ...”看起来是一个很好的问题。