赞
踩
一、结构体
概述:简单来说结构体就是一些值的集合,这些值是它的成员,只不过各个成员可能具有不同的类型。
结构体的声明:一种不完全声明,一种采用重命名typedef,再就是标准命名。
不完全声明:不声明结构体的tag:就是匿名声明。
重命名:将struct student重命名为student。
标准命名:什么都不省略。
注意:在同一个程序中,不同的结构体定义相同类型的相同变量,是不同的变量。
结构体成员:可以是不同类型的变量的集合,也可以只有一个类型的集合。
结构体成员的访问:直接访问:点操作符(.)访问;间接访问:->操作符简称箭头操作符。
注意:点操作符的优先级高于箭头操作符。
结构体的自引用:结构体自引用自己是非法的,因为包含自己的结构体中还包含自己的结构体,这样将重复下去永无止境。但在结构体中定义自己的结构
体指针是合法的,因为编译器在结构体长度确定之前就已经直到指针的长度,可以这样说这个指针其实是指向同一种类型的不同结构。
结构体的初始化:其实结构体的初始化和数组的初始化很像。位于花括号之内,由逗号分隔的初始化列表。
结构体的存储分配:存在一种边界对齐的说法。
方法:1.第一个成员在结构体变量编译量为0的地址处。
2.其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。
对齐数=编译器默认的一个对齐数与该成员大小的较小值。vs中默认值为8 inux中默认值为4
3.结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍。
4.如果嵌套了结构体,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数的整数倍。
修改默认值:需要预处理指令#pragma,直接在头文件上添加#pragma pack(默认的值)。
边界对齐的使用:1.尽可能的边界对齐,为了减少访问内存的次数;2.必要时可以不边界对齐,为了提高程序的可维护性和可读性。
结构体的传参:一个是传递结构体,一个是传递结构体的指针。
结构体:一般情况下,结构体的大小都很大,这时再用结构体传参就会开销很大;很小时可以传递,效率也很高。
指针:传递很大的结构体,用指针可以很大程度的减小开销,通过对指针的间接访问就可以得到结构体的值。
提示:函数参数传递的时候是需要圧栈。参数亚栈系统开销比较大。
二、联合
概述:联合的声明和结构体类似,但行为方式和结构不同,联合的所有成员引用的是内存中的相同的位置。
使用:当需要在不同时刻把不同的东西存储于同一个位置时,就可以使用联合体。
长度:它的长度就是联合中最长成员的长度。
初始化:必须是联合第一个成员的类型,而且它必须位于一对花括号里。
三、位段
关于结构体还必须知道位段。。
概述:声明和结构体类似,但是有两个例外,一是成员必须声明为int、signed int或unsigned int类型;其次,在成员名后面是一个冒号和一个整数,这个整数指定该位所占用的位的数目。
位段的可移植性:可移植性很差,注重可移植性的程序应该避免使用位段,具体原因如下:
1.int位段被当做有符号数还是无符号数是不确定的。
2.位段中最大位的数目不能确定。一个能够运行在32位整数的机器上的位段声明可能在16位整数的机器上无
无法行。
3.位段中的成员在内存中是从左到右分配的还是从右到左分配的标准尚未定义。
4.当一个结构包含两个位段,第二个位段成员比较大,无法容纳于第一个位段剩余的位时,是舍弃剩余的位
还是利用,这是不确定的。
与结构体相比:位段可以达到同样的效果,同时可以很好的节省空间,但是有跨平台的问题存在。
四、枚举
概述:enum 类型名 {};{}中的内容是枚举类型的可能取值,也叫枚举常量。这些可能取值都是有值得,默认从0开始,依次递增,一次递增1,也可以赋初值。
与#define定义常量相比枚举的优点:1.增加代码的可读性和可维护性。
2.和#define定义的标识符比较枚举有类型检查,更加严谨。
3.防止了命名污染(封装)。
4.便于调试。
5.使用方便,一次可以定义多个常量。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。