C语言中有的内置类型:char,int,short,long,long long,float,double,long double
自定义类型:枚举-enum,结构体-struct,联合体-unio
结构体的声明
一,结构体可以不完全声明
警告:
匿名类型的结构体,如果没有对结构体进行重命名,基本上只能用一次。
二,结构体的自引用
三,对齐规则
(1)结构体的第一个成员对齐到和结构体变量的起始位置偏移量为0的地址处。
(2)其他成员变量要对齐到某个数字(对齐数)的整数倍地址。
对齐数=编译器默认的一个对齐数 与 与该成员变量的较小值。
(3)结构体总大小为最大的对齐数(结构体成员变量都有一个对齐数,所以对齐数的最大值)的整数值。
(4)如果嵌套了结构体的情况,嵌套的结构体成员对齐到自己的成员中的最大对齐数的整数倍,结构体的大小就是对齐数的最大整数倍(含有嵌套结构体的最大对齐数的整数倍)。
其中,vs中为‘8’,Linux和gcc没有默认对齐数。
那为什么存在内存的对齐
(1)平台原因
(2)性能原因
四,修改默认对齐数
#pragma 这个预处理指令,可以改变编译器的默认对齐数。
结构体的默认对齐方式不合适时候,我们可以自己更改默认对齐数。
五,结构体传参
如果需要选择print和print1,因该是print1更好。
原因:(1)函数传参的时候,函数是需要压栈,会有时间和空间上系统的开销。(2)如果传递一个结构体对象的时候,结构体过大,参数压栈的系统开销比较大,所以会导致性能的下降。
结论:结构体传参的时候,要传结构体的地址。
六,结构体位段。
(1)位段的成员必须为int,unsigned,signed int。
(2)位段的成员后边有一个冒号和一个数字。
位段跨平台问题
(1)int位段被当成有符号还是无符号数是不确定的。
(2)位段中最大位的数目是不能确定的。
(3)位段中的成员从左向右分配,还是从右到左分配尚未定义。
(4)一个结构包含两个位段,第二个位段成员比较大,无法容纳在第一个位段剩余的位时,是舍弃还是利用,这是不确定的。
总结:跟结构相比,位段可以达到同样的效果,并且可以很好的节省空间,但是有跨平台的问题存在。
位段的使用的注意
的⼏个成员共有同⼀个字节,这样有些成员的起始位置并不是某个字节的起始位置,那么这些位
置处是没有地址的。内存中每个字节分配⼀个地址,⼀个字节内部的bit位是没有地址的。所以不能对位段的成员使⽤&操作符,这样就不能使⽤scanf直接给位段的成员输⼊值,只能是先输⼊放在⼀个变量中,然后赋值给位段的成员