- 前言
- 一、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位。
1、来源
*_t表示该标识由typedef定义得到,是结构的一种标注。
C语言代码中的uint8_t / uint16_t / uint32_t /uint64_t都不是新的数据类型,而是通过typedef给数据类型起得新名字,如:
typedef signed char int8_t;
typedef short int int16_t;
typedef int int32_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_t num=67;
cout << num << endl; //输出结果为C
四、typedef的用法及与define的区别
1、typedef的用法
typedef并不创建新的类型,而仅仅为现有类型添加一个别名。
常用于创建易于记忆的类型名称,用它来表示我们的真实意图,如
typedef int int32_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 *;
PSTRING1 p1, p2;
PSTRING2 p3, 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) 。
参考:
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
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)