对于类型有这样的分法:
内置类型:
- char
- short
- int
- long
- long long
- float
- double
自定义类型:
- 结构体
- 枚举
- 联合
结构体:
当我们描述一个对象 但发现他有许多属性时 这时候这些属性就是结构体的成员变量 这些成员变量可以时不同的类型 也就时有着不同的属性
经典的结构体是这样的 struct stu //stu 是标签 因为有时我们需要用到多个结构体 那么标签就是为了区别他们 { 如果不要标签 那他就是匿名结构体 后面会说到 memberlist 成员列表 }variablelist 变量列表 s1 s2 s3
如果你对把一个结构体赋值给另一个结构体 即使两个结构体成员变量相同 但他们时匿名结构体的话 那么是不可以的 因为编译器会认为你左右的两个类型时不同的
定义的方法: struct stu { ~~~~~~ }s1={~~~~}; int main() { struct stu s2={~~~~~~}; }
结构体的内存对齐:
在了解结构体的内存对齐之前首先我们要知道一个 宏 offsetoff
这个可以返回一个结构体成员在结构体里面偏移量的大小 记住他的头文集 <stddef.h>
#include <stdio.h> #include <stddef.h> struct stu { char i; int c; }s1; int main() { printf("%d",offsetof(struct stu,i)); //0 printf("%d",offsetof(struct stu,c)); //4 }
我们再定义一个结构体来解释这个现象
我们先看看内存对齐的规则
①第一个成员在结构体偏移量为0的地址处
②其他成员变量(从第二个变量开始)要对齐到某个数字(对齐数)的整数倍的地址处
对齐数是编译器默认的一个对齐数 与 该成员大小的 最小值
vs默认对齐数是 8
③结构体的总大小为最大对齐数的整数倍
④如果嵌套了结构体的情况 嵌套的结构体对齐到自己的最大对齐数的整数倍,结构体的整体大小就是所有最大对齐数(含嵌套结构体里面的对齐数)的整数倍
(linux没有默认对齐数 对齐数就是其自身的大小)
为什么存在内存对齐?
平台原因(移植原因):不是所有的硬件平台都能访问任意地址上的任意数据;某些硬件平台只能再某些地址处去某些特定的类型数据
性能原因:数据结构(尤其是栈)应该尽可能的在自然边界上对齐
其实总的来讲内存对齐 就是 空间换时间的做法
同样默认对其数是可以修改的 使用 #pragma pack(8) 就可以修改默认对齐数为8
使用 #pragma pack()还原默认对齐数
其次对于结构体传参 还是传地址的要好