在C 中使用uint8_tover有什么好处unsigned char?
我知道几乎每个系统uint8_t都只是一个typedef unsigned char,为什么要用呢?
Mar*_*som 212
它记录了你的意图 - 你将存储小数字而不是字符.
如果你正在使用其他类型的定义,例如uint16_t或,它看起来更好int32_t.
Chr*_*utz 64
只是为了迂腐,一些系统可能没有8位类型.根据维基百科:
当且仅当它具有满足要求的任何类型时,才需要实现为N = 8,16,32或64定义精确宽度的整数类型.即使它支持适当的类型,也不需要为任何其他N定义它们.
因此uint8_t不能保证存在,但它适用于8位= 1字节的所有平台.一些嵌入式平台可能会有所不同,但这种情况非常罕见.某些系统可能将char类型定义为16位,在这种情况下,可能不会是任何类型的8位类型.
除了那个(小)问题,@ Mark's Ransom的答案在我看来是最好的.使用最清楚地显示您正在使用数据的那个.
另外,我假设你的意思是uint8_t(stdint.h标题中提供的C99标准typedef )而不是uint_8(不是任何标准的一部分).
AnT*_*AnT 40
重点是编写与实现无关的代码.unsigned char不保证是8位类型.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()
Run Code Online (Sandbox Code Playgroud)
您使用哪种方法取决于您的编译器.您可能还需要支持具有相同头文件的多个不同编译器.这种情况发生在设备和服务器可能完全不同的嵌入式系统中 - 例如,您可能拥有与x86 Linux服务器通信的ARM设备.
使用包装结构有一些注意事项.最大的问题是你必须避免取消引用成员的地址.在具有多字节对齐单词的系统上,这可能导致未对齐的异常 - 以及coredump.
有些人还担心性能,并认为使用这些打包结构会降低系统速度.确实,在幕后,编译器添加了访问未对齐数据成员的代码.您可以通过查看IDE中的汇编代码来查看.
但由于打包结构对于通信和数据存储最有用,因此在内存中处理数据时可以将数据提取为非打包表示.通常我们不需要在内存中处理整个数据包.
以下是一些相关的讨论:
pragma pack(1)也不是__attribute __((aligned(1)))有效
gcc的__attribute __((打包))/ #pragma包不安全吗?
http://solidsmoke.blogspot.ca/2010/07/woes-of-structure-packing-pragma-pack.html
没什么.从可移植性的角度来看,char不能小于8位,并且没有什么可以小于char,所以如果给定的C实现具有无符号的8位整数类型,那么它将是char.或者,它可能根本没有一个,此时任何typedef技巧都没有实际意义.
它可用于更好地记录您的代码,因为很明显您需要8位字节而不需要其他内容.但实际上它几乎已经在任何地方都是合理的期望(有些DSP平台并不是真的,但是你的代码在那里运行的可能性很小,你也可以在你的程序顶部使用静态断言错误输出这样一个平台).
| 归档时间: |
|
| 查看次数: |
279161 次 |
| 最近记录: |