uint8_t / uint16_t / uint32_t /uint64_t 这些数据类型是 C99 中定义的,它就是一个结构的标注,可理解为type/typedef的缩写,表示通过typedef定义。它们只是使用typedef给类型起的别名 #ifndef _UINT8_T #define _UINT8_T typedef unsigned char uint8_t; #endif /* _UINT8_T */ #ifndef _UINT16_T #define _UINT16_T typedef unsigned short uint16_t; #endif /* _UINT16_T */ #ifndef _UINT32_T #define _UINT32_T typedef unsigned int uint32_t; #endif /* _UINT32_T */ #ifndef _UINT64_T #define _UINT64_T typedef unsigned long long uint64_t; #endif /* _UINT64_T */ 一般来说,一个C的工程中一定要做一些这方面的工作,因为你会涉及到跨平台,不同的平台会有不同的字长,所以利用预编译和typedef可以让你最有效的维护你的代码。为了用户的方便,C99标准的c语言硬件为我们定义了这些类型,我们放心使用就可以了。这样使用的方便之处, 如: typdef unsigned int uint32_t; 表示uint32_t为32位无符号类型数据, 其实size_t也是32位无符号数据类型, 为什么不直接写"unsigned int"呢?为了程序的可扩展性, 假如将来我们需要的数据大小变成了64bit时,我们只需要将typedef long long size_t就可以了, 不然我们可要修改好多好多的地方了. 照posix标准,一般整形对应的*_t类型为: 1字节 uint8_t 2字节 uint16_t 4字节 uint32_t 8字节 uint64_t 准确地说是 32 位,未必是 4 个字节,因为 C 标准没有规定一个字节几位(虽然大部分系统确实都是 8 位)。 格式化输出: unit64_t %llu unit32_t %u unit16_t %hu 注意: 必须小心 uint8_t 类型变量的输出,例如如下代码: uint8_t fieldID = 67; cerr<< "field=" << fieldID <<endl; 结果发现是:field=C 而 不是我们所想的 field=67 这是由于 typedef unsigned char uint8_t; uint8_t 实际是一个 char, cerr << 会输出 ASCII 码是 67 的字符,而不是 67 这个数字. 因此,输出 uint8_t 类型的变量实际输出的是其对应的字符, 而不是真实数字. 若要输出 67,则可以这样: cerr<< "field=" << (uint16_t) fieldID <<endl; 结果是:field=67 同样: uint8_t 类型变量转化为字符串以及字符串转化为 uint8_t 类型变量都要注意, uint8_t类型变量转化为字符串时得到的会是ASCII码对应的字符, 字符串转化为 uint8_t 变量时, 会将字符串的第一个字符赋值给变量. 这种设计我们同样可以应用到自己的开发中来,当自己设计一个int类型保存某种数据时,但你又没把握将来是不是要用long int时你可以引用一个自己定义的数据类型的啊! 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 int main(int argc, const char * argv[]) { @autoreleasepool { uint32_t a; a = 12; printf("a = %x\n",a); printf("sizeof(a) = %lu\n",sizeof(a)); uint64_t b; b = 12; printf("b = %x\n",b); printf("sizeof(b) = %lu\n",sizeof(b)); } return 0; } 打印结果