天天看点

iOS开发系列--C语言之构造类型概述结构体枚举共用体

在第一节中我们就提到c语言的构造类型,分为:数组、结构体、枚举、共用体,当然前面数组的内容已经说了很多了,这一节将会重点说一下其他三种类型。

<a href="http://www.cnblogs.com/kenshincui/p/3856543.html#struct">结构体</a>

<a href="http://www.cnblogs.com/kenshincui/p/3856543.html#enum">枚举</a>

<a href="http://www.cnblogs.com/kenshincui/p/3856543.html#union">共用体</a>

数组中存储的是一系列相同的数据类型,那么如果想让一个变量存储不同的数据类型就要使用结构体,结构体定义类似于c++、c#、java等高级语言中类的定义,但事实上它们又有着很大的区别。结构体是一种类型,并非一个变量,只是这种类型可以由其他c语言基本类型共同组成。

对于上面的例子需要做出如下说明:

可以在定义结构体类型的同时声明结构体变量;

如果定义结构体类型的同时声明结构体变量,此时结构体名称可以省略;

定义结构体类型并不会分配内存,在定义结构体变量的时候才进行内存分配(同基本类型时类似的);

结构体类型的所占用内存大型等于所有成员占用内存大小之和(如果不考虑内存对齐的前提下);

iOS开发系列--C语言之构造类型概述结构体枚举共用体

表格具体来源请观看下面的视频(注意由于录制软件的原因前几秒不清晰但是不影响分析):

接下来看一下结构体数组、指向结构体的指针:

结构体作为函数参数传递的是成员的值(值传递而不是引用传递),对于结构体指针而言可以通过”-&gt;”操作符进行访问。

枚举类型是比较简单的一种数据类型,事实上在c语言中枚举类型是作为整形常量进行处理的,通常称为“枚举常量”。

需要注意的是枚举成员默认值从0开始,如果给其中一个成员赋值,其它后面的成员将依次赋值,例如上面如果summer手动指定为8,则autumn=9,winter=10,而sprint还是0。

共用体又叫联合,因为它的关键字是union(貌似数据库操作经常使用这个关键字),它的使用不像枚举和结构体那么频繁,但是作为c语言中的一种数据类型我们也有必要弄清它的用法。从前面的分析我们知道结构体的总长度等于所有成员的和(当然此时还可能遇到对齐问题),但是和结构体不同的是共用体所有成员共用一块内存,顺序从低地址开始存放,一次只能使用其中一个成员,union最终大小由共用体中最大的成员决定,对某一成员赋值可能会覆盖另一个成员。

这里需要重点解释一个问题:为什么t.a、t.b、t.c输出结果分别是4、260、65796,当然t.c等于65796并不奇怪,但是t.a前面赋值为’a’不应该是97吗,而t.b不应该是10吗?其实如果弄清这个问题共用体的概念基本就清楚了。

根据前面提到的,共用体其实每次只能使用其中一个成员,对于上面的代码经过三次赋值最终使用的其实就是t.c,而通过上面的输出结果我们也确实看到c是有效的。共用体有一个特点就是它的成员存储在同一块内存区域,这块区域的大小需要根据它的成员中长度最大的成员长度而定。由于上面的代码是在64位编译器下编译的,具体长度:char=1,short int=2,int=4,所以得出结论,type的长度为4,又根据上面输出的地址,可以得到下面的存储信息(注意数据的存储方式:高地址存储高位,低地址存储地位):

iOS开发系列--C语言之构造类型概述结构体枚举共用体

当读取c的时候,它的二进制是“00000000  00000001  00000001  00000100”,换算成十进制就是65796;而经过三次赋值后,此时b的存储就已经被c成员的低位数据覆盖,b的长度是二,所以从起始地址取两个字节得到的二进制数据此时是“00000001  00000100”(b原来的数据已经被c低2位数据覆盖,其实此时就是c的低2位数据),换算成十进制就是260;类似的a此时的数据就是c的低一位数据”00000100”,换算成十进制就是4。