C语言|C语言数据类型及typedef下的uint8_t / uint32_t


文章目录

  • 前言
  • 一、C语言基本数据类型
  • 二、数据类型在不同编译器下存在的字长差异
  • 三、uint8_t / uint16_t / uint32_t /uint64_t的来源和作用
  • 四、typedef的用法及与define的区别
  • 总结

前言 在基于C语言的代码中总能看到uint8_t / uint16_t / uint32_t /uint64_t的身影。如:uint32_t a = 300;
但它似乎又不属于C语言中的6种基本数据类型(short、int、long、char、float、double),那么它是一种新的数据类型?
本文以这个问题为切入点,回顾了C语言中的6种基本数据类型;描述了数据类型在不同编译器、平台存在的字长差异;进而引出了uint8_t / uint16_t / uint32_t /uint64_t的来源和作用;最后介绍了typedef的用法及与define的区别。
一、C语言基本数据类型 C语言共有6种基本数据类型,分别是:
1)整型:short、int、long;
2)浮点型:float、double;
3)字符类型:char。
二、数据类型在不同编译器下存在的字长差异 C语言的6种基本数据类型中,int类型(整型-short、int、long)比较特殊,其具体的字节数同机器字长和编译器有关。下面对比数据类型在16位、32位、64位编译器下的字节长度,用sizeof( )函数得出。
注:
① 这里的编译器位数指的是编译生成的软件(应用程序)的位数;
② char型从本质上说,也是种整型类型,它是长度为1的整数,通常用来存放字符的ASCII码。

16位编译器:
char// 1个字节 char*// 2个字节(*指针变量) // 16位的寻址空间是2^16, 即16个bit,即2字节。(32位、64位编译器同理)short int// 2个字节 int// 2个字节 unsigned int// 2个字节 无符号整型float// 4个字节 double// 8个字节long// 4个字节 long long// 8个字节 unsigned long// 4个字节

32位编译器:
char// 1个字节 char*// 4个字节(*指针变量)(16&32&64位机各不相同)short int// 2个字节 int// 4个字节(16位-2B,32&64位-4B(Byte)) unsigned int// 4个字节(16位-2B,32&64位-4B)float// 4个字节 double// 8个字节long// 4个字节(16&32位-4B,64位-8B) long long// 8个字节 unsigned long// 4个字节(16&32位-4B,64位-8B)

64位编译器:
char// 1个字节 char*// 8个字节short int// 2个字节 int// 4个字节 unsigned int// 4个字节float// 4个字节 double// 8个字节long// 8个字节 long long// 8个字节 unsigned long// 8个字节

如上所示,int,long int,short int的数据位宽与编译器有关。但存在以下原则(ANSI/ISO制订),即
1) sizeof(short int) <= sizeof(int) ;
2) sizeof(int) <= sizeof(long int) ;
3) short int至少应为16位(2字节) ;
4) long int至少应为32位。
三、uint8_t / uint16_t / uint32_t /uint64_t的来源和作用 1、来源
*_t表示该标识由typedef定义得到,是结构的一种标注。C语言代码中的uint8_t / uint16_t / uint32_t /uint64_t都不是新的数据类型,而是通过typedef给数据类型起得新名字,如:
typedef signed charint8_t; typedef short intint16_t; typedef intint32_t;

2、作用
1)增加代码的可读性
uint8_t,uint32_t能更明显的显示所占字节数。
uint8_t表示占1个字节(1 字节=8 bit);
uint32_t表示占4个字节(4 字节=32 bit)。
2)增加代码的可维护性
在涉及到跨平台时,不同的平台会有不同的字长,所以利用预编译和typedef可以方便的维护代码。
注:uint8_t实际上就是一个char,所以输出 uint8_t类型的变量实际上输出对应的字符,而不是数值,如:
uint8_tnum=67; cout << num << endl; //输出结果为C

四、typedef的用法及与define的区别 1、typedef的用法
typedef并不创建新的类型,而仅仅为现有类型添加一个别名。常用于创建易于记忆的类型名称,用它来表示我们的真实意图,如
typedef intint32_t; // typedef定义了一个int的同义字int32_t,可在任何需要int的上下文中使用int32_t。

2、typedef 与define 的区别
1)typedef 行为有点像 define 宏,用其实际类型替代同义字;
2)不同点是typedef 在编译时会被解释,因此让编译器来应付超越预处理器能力的文本替换,即不是简单的文本替换。
3)#define优势:可以使用#ifdef ,#ifndef等来进行逻辑判断,使用#undef来取消定义。
4)typedef优势:它受范围规则约束,使用typedef定义的变量类型其作用范围限制在所定义的函数或者文件内(取决于此变量定义的位置),而宏定义则没有这种约束。
案例一:
typedef char *pStr; define pStr char *;

通常来说,上面两种定义pStr数据类型的方法中,typedef要比 define宏要好,特别是在有指针的场合。请看例子:
typedef char *PSTRING1; #define PSTRING2 char *; PSTRING1p1, p2; PSTRING2p3, p4;

在上述的变量定义中,p1、p2、sp3都被定义为char *,p4则定义成了char,而不是我们所预期的指针变量,根本原因在于 define 只是简单的字符串替换;而 typedef 则是为一个类型起新名字。
注:使用 #define 定义时,如果定义中包含表达式,必须使用括号,即 #define f(x) (xx) ;
案例二:
typedef char * pStr; char string[4] = "abc"; const char *p1 = string; const pStr p2 = string; p1++; p2++;

上述代码中 const pStr p2 并不等于 const char * p2;
const pStr p2:限定数据类型为char *的变量p2为只读,因此p2++错误;
const char * p2(const修饰的是前面的char):可以对任意位置(非系统敏感区域)进行“只读” 操作。(“只读”是相对于char * p2来说所限定的内容)。
总结 1) C语言共有6种基本数据类型:short、int、long;float、double;char;
2) 数据类型(int类型(整型-short、int、long)比较特殊),其具体字节数与编译器位数有关;
3) uint8_t / uint16_t / uint32_t /uint64_t不是新的数据类型,而是通过typedef给数据类型起的新名字;
4) typedef的合理运用可增加代码的可读性、可维护性;
5) typedef不是简单的文本替换,#define 定义时,如果定义中包含表达式,必须使用括号,即 #define f(x) (xx) 。
【C语言|C语言数据类型及typedef下的uint8_t / uint32_t】参考:
https://blog.csdn.net/mary19920410/article/details/71518130
https://blog.csdn.net/bzhxuexi/article/details/19551979
https://blog.csdn.net/qq_44770155/article/details/90602325

    推荐阅读