结构体:
我们通常所见数据大多成组出现,即它们的数据类型相同,但是如果数据类型不同怎么办?例如,描述一个学生的信息,包含姓名,年龄,性别等,它们数据类型不同,无法存储于同一个数组中,在C语言中,我们可以通过使用结构把不同类型的值存储在一起。
结构体声明举例代码如下:
struct Stu
{
char name[20];
int age;
char id[15];
};//注意:分号不能丢
结构体成员访问:
(1)结构成员的直接访问:结构变量的成员是通过点操作符(.)访问的。左操作数就是结构变量的名字,右操作数就是需要访问的成员的名字
(2)结构体成员的间接访问:如果你拥有一个指向结构体的指针,我们首先应该做的是对指针执行间接访问操作,获得这个结构,然后使用点操作符来访问呢它的成员
struct Stu
{
char name[20];
int age;
char id[15];
}s;
void print(struct Stu* s)
{
printf("%d,%s",(*s).name,(*s).age,(*s).id);
printf("%s %d\n",s->name,s->age,s->id);
}
注意:结构体的间接访问形式有两种,建议选择第二种。即(->)方式。
结构体的内存对齐(*****)
这个知识点非常重要!!!
内存对齐我们要了解两个问题:
(1)为什么存在内存对齐?
答:
1.平台原因:不是所有硬件平台都能访问任意地址上的任意数据的;
2.性能原因:数据结构(尤其是栈)应该尽可能的在自然边界对齐,原因在于,为了访问未对齐的内存,处理器需要两次内存访问,而对齐的内存只需要一次访问即可。
总的来说:这是一种拿空间换取时间的做法。
(2)内存对齐的规则是什么?
答:
1. 结构体的第一个成员永远对齐到结构体起始位置的0偏移处;
2.从第二个成员开始,每个成员都对齐到【对其数】的整数倍处;
【对齐数】:为成员自身大小和【默认对齐数】的较小值;
【默认对齐数】:linux--4字节 windows--8字节;
3.结构体的总大小时所有对齐数中最大对齐数的整数倍;
4.如果结构体嵌套了结构体,那么嵌套的结构体对齐到自己的最大对齐数的整数倍处,
结构体的整体大小就是所有最大对齐数(包含嵌套结构体的对齐数)的整数倍。
结构体传参:
注意:结构体传参的时候要传结构体的地址
因为如果你想要传一个结构体对象的时候,假如结构体过大,那么在参数压栈时,系统开销过大,造成性能下降,
所以选择传结构体的地址。
位段:
请注意:位段的概念十分重要,因为它可以极大的减少内存的浪费,具体优点向后看----》》》
什么是位段?
位段的声明和结构体十分相似,主要有两大区别:
一是:位段的成员必须是int ,unsigned int ,signed inrt
二是:位段的成员名后面有一个冒号和一个数字
位段举例:
struct A//定义一个位段
{
int a : 2; //是两个bit位;
int b : 5;
int c : 10;
int d : 30;
};
int main()
{
printf("%d\n",sizeof(struct A));//8个字节
system("pause");
return 0;
}
注意:1字节=8bit
关于位段你需要注意的事情:
1.位段是不跨平台的,因此,注重可移植的程序应该避免使用位段
2.int 位段被当成是有符号数还是无符号数不确定的,
3.位段中的成员在内存中是从左到右发分配还是从右到左分配是不确定的。
4.当一个结构体包含两个以上位段时,从第二个开始,无法容纳于第一个位段剩余的位时,是舍弃还是利用?未知!!!
当然,对于一般而言,位段的内存分配就像是你想的那样,具体可以写代码测出来。
总的来说,位段只要不考虑跨平台问题,可以达到很好的节省空间。
枚举
枚举举例:
enum Sex//定义一个性别枚举
{
MALE,
FEMALE,
SECRET
};//---->分号不可少
注意:{}内部的内容是枚举类型的可能取值,也称为枚举常量,默认从0开始,一次递增1;
枚举的优点:(*****):
1.增加代码的可读性和可维护性
2.防止了命名污染(封装),即:防止命名冲突
3.便于调试;
4.使用更方便,一次可以定义多个变量;
5.枚举有类型检查,和#define定义的标识符相比,更加严谨;
联合(共用体)
联合的特点:这些类型定义的变量包含一系列的成员,特点是这些成员共用同一块内存空间
联合举例:
union Un//联合类型的声明
{
char c;
int i;
};
union Un un;//联合变量的定义
int main()
{
printf("%d\n",sizeof(union Un));
system("pause");
return 0;
}
联合大小的计算:
1.联合的大小至少为最大成员的大小
2.当联合的大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍。
举例说明:
union Un1
{
char c[5];//1
int i;//4
};
int main()
{
printf("%d\n",sizeof(union Un1));//8
system("pause");
return 0;
}