赞
踩
前面我们讲过一些结构体的知识这里不在叙述,补充一些没有的
匿名结构体有两点需要注意
1.匿名结构体只能使用一次,在创建的时候就要有变量,相当于全局变量。
2.两个匿名结构体虽然声明都是一样的,但是编译器会把这两个声明当成完全不同的两个类型
在结构中包含一个类型为该结构本身的成为是否可以呢?
上面这种自引用是不可以的,如果这样声明,sizeof(struct Node)需要开辟多大空间。
采用这种方法,我只需要放一个int型数据大小,再放一个struct Node*指针大小就可以,这个指针会帮我找到下一个数据的位置。
前面文章讲过结构体内存对齐规则,但是并没有讲结构体嵌套结构体,下面就讲讲这种。
如果嵌套了结构体先把嵌套的结构体总大小算出来,然后按照第2条规则放第一个成员的位置。弄完嵌套的,再算其他的的成员。
为什么会有结构体内存对齐?
1.平台原因(移植原因)
不是所有的硬件平台都能随意访问任意地址上的任意数据;某些硬件平台只能在某些地址处取某些特定类型的数据;否则抛出硬件异常
2.性能原因
数据结构(尤其是栈)应该尽可能地在自然边界对齐
原因在于,对于访问未对齐的内存,处理器需要做两个内存访问;而对齐的内存访问仅需要一次访问
总的来说
结构体的内存对齐就是拿空间来换取时间的做法
那么设计结构体的时候,我们既要满足对齐,又要节省空间,如何做到:
让占用空间小的成员尽量集中在一起
结构体有两中传参方式,但是我们知道形参是实参的临时拷贝,如果实参过大,传给形参,形参也会开辟一大片空间,这样浪费了内存空间,
所以结构体传参要传地址
位段的声明和结构体类似,但有两个不同
1.位段的成员必须是int,unsigned int,signed int或者char(char属于整型家族)
2.位段的成员名后边有一个冒号和数字
这样一个位段的大小是多少;
位段的空间是按照4个字节(int)或者1个字节(char)的方式开辟的
就如上面,先开辟了一个int大小的字节,32个byte,a,b,c共占17个,还剩下15个。但是要分配给d的不够,所以又开辟了一个int大小字节。
使用位段的意义:
比如你用一个int a=2;这样会开辟4个byte,32个bit位,但是2的二进制00000000 00000000 00000000 00000010;
只需要保存最后两位01;就可以把2保存下来,
这样做是为了节省内存空间
1.int位段被当成有符号还是无符号数是不确定的
2.位段中最大的数目不能确定
3.位段的中的成员在内存中从左向右分配,还是从右向左分配标准尚未定义
4.当一个结构包含两个位段时,第二个位段比较大,无法容纳于第一个位段剩余位时,是否舍弃剩余的位还是利用,还是不确定的。
枚举顾名思义就是一一列举
把可能的取值一一列举
比如
性别,月份,等等
{ }中的内容是枚举类型的可能取值,也叫枚举常量
这些可能取值都是有值,默认从0开始,依次递增1,当然在定义中时候也可以赋初值
我们可以使用#define定义常量,那为什么非要使用枚举?
枚举的优点
增加代码的可读性和可维护性
和#define定义的标识符比较枚举有类型差错,更加严谨
防止了命名污染
便于调试
使用方便,一个可以定义多个常量
注意只能拿枚举常量给枚举变量赋值,才不会出现类型差异,比如day=5;这样就是把int转化给enum Day会出现问题
联合也是一种特性的自定义类型
这种类型定义的变量也包含了一系列的成员,特征是这些成员公用同一块空间
联合的成员是共用同一块内存空间,这样一个联合变量的大小,至少是最大成员的大小(因为联合至少得有能力保存最大得那个成员)
联合的大小至少是最大成员的大小
当最大成员大小不是最大对齐数的整数倍时,就要对齐到最大对齐数的整数倍。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。