目录
结构体
结构体的定义:
结构是一些值的集合,这些值称为成员变量。
结构的每个成员可以是不同类型的变量。
结构体类型的定义:
struct Stu
{
//学生的相关信息
char name[20];
int age;
}s1,s2;//s1,s2是struct Stu类型的变量(全局变量)
int main()
{
struct Stu s3;//局部变量
system("pause");
return 0;
}
struct
{
int a;
char b;
float c;
}x;
struct
{
int a;
char b;
float c;
}a[20],*p;
int main()
{
p = &x; 从“*”到“*”的类型不兼容
return 0;
}
结构体的自引用
数据结构:数据在内存中的存储结构
线形-顺序表、链表
树形-二叉树
结构体的定义和初始化
结构体的对齐
对齐的规则:
例题:求所占空间的字节数。
struct S3
{
double d;
char c;
int i;
};
int main()
{
printf("%d\n", sizeof(struct S3));
system("pause");
return 0;
}
解析:
最终结果为16。
为什么会存在内存对齐?
总的来说,内存对齐就是拿空间来换取时间的做法。
(1)平台原因—移植原因
不是所有的硬件平台都能访问任意地址上的任意数据;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。
(2)性能原因
数据结构(尤其是栈)应该尽可能地在自然边界上对齐。
原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访问。
关于默认对齐数
(1)可以修改
(2)挨着放,设为1即可
延申:
结构体传参
传值调用
传址调用
传值调用与 传址调用的比较
传值调用更好
原因:函数传参数时,参数是需要压栈,会有时间和空间上的系统开销。
如果传递一个结构体对象的时候,结构体过大,参数压栈的系统开销比较大,所以会导致性能的下降。
位段
是用来节省空间的
什么是位段?
位段的声明和结构是类似的,有两个不同:
1.位段的成员必须是 int 、unsigned int 、signed int
2.位段的成员名后面有一个冒号和一个数字
位段的内存分配
结果为3,浪费掉了前面的一个比特位!
枚举
enum Day
{
Mon,
Tues,
Wed,
Thur,
Fri,
Sat,
Sun
};
int main()
{
//enum Day d = Fir;
printf("%d\n", Mon);
printf("%d\n", Tues);
printf("%d\n", Wed);
system("pause");
return 0;
}
可以修改,初始化第一个:
枚举的优点
联合(共用体)
联合的特点
联合的成员共用同一块内存空间,这样一个联合变量的大小,至少是最大成员的大小(因为联合至少得有能力保存最大的那个成员)。
联合体也存在对齐,到最大对齐数的整数倍。
例题:
判断大小端
int check_sys()
{
union MyUnion
{
char c;
int i
}u;
u.i = 1;
return u.c;
}
int main()
{
int ret = check_sys();
if (ret == 1)
{
printf("小端\n");
}
else
{
printf("大端\n");
}
system("pause");
return 0;
}
联合大小的计算
(1)联合的大小至少是最大成员的大小
(2)当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍。