上一篇文章提到了C语言中的关键字,主要介绍了基础数据类型和修饰符的关键自己,这一篇主要记录一下对于数据结构方面的几个关键字。
struct
struct即是我们所说的结构体。他将一些相关联的数据打包成一个整体,方便使用。
其实它的概念通俗的来说,就像OOP语言中的类一样,只不过我们的结构体里没有函数,只有各种“属性”或者“字段”。(PS:C语言中只能包含数据,C++中可以包含成员函数,和class更加相似,C语言中也可以实现类似成员函数的方式,利用函数指针可以做到像OOP一样类似的封装)
说到结构体,最折磨人的就是它的大小问题。 普通结构体的大小涉及到内存对齐,位域访问的问题,这个部分内存对齐的只是将在另一边文章中整理,首先我们先看一下空结构的大小问题,大小是0吗? 很遗憾,大小是1。
如果定义一个空结构体,把它看成一个模子,模子当然不能为0。编译器认为任何一种数据类型都有其大小,同样它也认为任何一个结构体都是有大小的,哪怕它是空的。
union
关键字union,即联合体。它和struct非常相像,但是含义却有较大的差别。
我们知道,struct结构体的大小是考虑到其中每个成员后,经过内存对齐(内存对齐主要是优化,为了更快的访问)而产生的。而union则只是维护足够的空间(即成员中大小最大的数据类型)来放置多个数据成员的一种,而并非给每个成员都配置空间。
所有的成员都有相同的起始地址。一个形象的比喻:struct就像是一个大别墅,每个成员都有自己的房子,大家都在里面住也没任何问题;而union就比较可怜了,只有一个房间,大小够成员中最胖的那个住进去,但是就像是多维空间,我们从不同的维度(类型或成员)看上去会看到不同的成员。
union主要的用处就是压缩空间。如果一些数据不可能在同一时间被用到,则他们可以写进同一个union里面。 另外一个用法就是用它来做一些数据结构的解析,比如数组到int的转换:
union CONVERT { int data[2]; char byte[8]; }Convert;
如果将通信中的数据流拷贝到Convert.byte数组中,通过读取Convert.data就可以得到int类型的数据。
enum
枚举类型一般它的定义如下:
enum enum_type_name { ENUM_CONST_1, ENUM_CONST_2, ...... ENUM_CONST_n }enum_variable_name;
其中里面的例如ENUM_CONST_1就是我们常说的枚举常量。
需要注意的一点是,enum中的常量可以赋值,但是如果你不给它赋值则会从被赋了初值的那个常量开始依次加1.如果没有给赋任何值,则从第一个值开始自动赋0,往后每个变量都自增1.
至于enum的大小,你在使用它的时候它的类型就已经确定了,这时大小你自己心里也就有数了。enum可以一次定义大量相关的常量,而且使用方便。
typedef
typedef关键字有许多人对这个关键字的认知是:定义一个“新的”数据类型。但是它的真正作用是:给一个已经存在的数据类型(注意,不是变量)取一个别名。
它的主要用处就是,取了别名之后我们可以更清楚的一眼看懂这个数据类型的含义,另一方面我们还可以自定义类型来做到平台兼容和系统移植。常见的使用场合就是结构体定义的时候。
typedef struct Student { //code.. }stu,*stu_p;
此时结构体Student 就有了别名stu,即
- struct Student stu1 等价于 stu stu1;
- struct Student* stu2 等价于 stu_p stu2 等价于 stu * stu2;
现在我们顺便回顾一下以前的知识:
const stu_p stu3; stu_p const stu4;
这两句的const分别修饰的是谁呢?
答案是stu3和stu4。因为我们说了typedef的含义是,给"数据类型"起一个别名。所以stu_p不单单是一个指针,而是一个数据类型。const在判断时会自动忽略数据类型,所以自然它也就被当作不存在啦。
© 版权声明
文章版权归作者所有,未经允许请勿转载。
相关文章
暂无评论...