当前位置 博文首页 > MOUYULOU的博客:自定义类型:结构体 枚举 联合体 那些你不知道
struct为结构体关键字,tag为结构体的标志,member-list为结构体成员列表,其必须列出其所有成员;variable-list为此结构体声明的变量。
struct tag
{
member_list;
}variable_list;
描述一个学生
struct stu
{
char name[20];//姓名
int age;//年龄
chae sex[5];//性别
};//分号不能少
特殊声明 在声明时可以不完全声明
struct//省略掉了结构体标签
{
int a;
char b;
}x;
结构体自引用
strcut Node
{
int data;
struct Node next;
};//这样是否可行?那么sizeof(struct Node)是多少?
显然上边这种方法无法计算sizeof(struct Node)是多少 下边是正确的自引用方式:
strcut Node
{
int data;
struct Node* next;
};
struct stu//声明结构体类型
{
char nam[20];//姓名
int age;//年龄
char sex[5];//性别
};
int main()
{
struct stu s1= { "zhangsan", 20, "nan" };//结构体初始化
printf("%s %d %s", s1.nam, s1.age, s1.sex);//访问结构体变量元素
return 0;
}
为什么结果是12?是如何计算?
首先我们先得掌握结构体对齐规则:
1.第一个成员在与结构体变量偏移量为0的地址处
2.其他成员变量对齐到某个数字(对齐数)的整数倍地址处
对齐数=编译器默认的一个对齐数与该成员大小的较小值
3.结构体总大小为最大对齐数的整数倍
4.如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体整体的大小就是所有最大对齐数的整数倍
那么为什么存在结构体对齐?
1.平台原因:不是所有硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据。
2.性能原因:数据结构(尤其是栈)应该尽可能的在自然边界上对齐。原因在于,为了访问未对齐的内存,处理器需要做两次访问,而对齐的内存访问仅需要访问一次。
在设计结构体时我们既要满足对齐,又要节省空间,就需要让占用空间小的成员尽量集中在一起。
修改默认对齐数
#pragma pack(8)//修改默认对齐数为8
什么是位段:1.位段的成员必须是 int unsigned int 或signed int
2.位段的成员名后边有一个冒号和一个数字
struct A
{
char a:3;
char b:4;
char c:5;
char d:4;
};
A就是一个位段
位段的内存分配
1.位段的成员可以说int unsigned int signed int 或char类型
2.位段的空间上是按照需要4字节(int)或者1字节(char)的方式来开辟的。
3.位段涉及很多不确定因素,位段是不跨平台的。
为什么?
枚举:把可能的取值列举出来
enum sex//性别
{
male;
female;
secret;
};
这些可能取值都是有值的,默认从0开始,一次递增1,也可在定义是赋初值
enum sex//性别
{
male=1;
female=2;
secret=4;
};
1.增加代码的可读性和可维护性
2.和#define定义标识符比较枚举有类型检查,更加严谨
3.防止命名污染
4.便于调试
5.使用方便,一次可以定义多个常量
联合是一种特殊的自定义类型 这种类型定义变量包含一系列成员,特征是这些成员公用同一块空间
//联合体类型声明
union un
{
char c;
int i;
};
//联合变量定义
union Un un;
//计算联合变量大小
printf("%d\n",sizeof(un));
联合的成员共用同一块内存空间,一个联合变量的大小,至少是最大成员大小
union Un
{
int i;
char c;
}un;
int main()
{
un.i = 0x11223344;
un.c = 0x55;
printf("%x\n", un.i);
}
用联合体判断计算机的大小端存储
int check_sys()//联合体大小端判断
{
union U
{
char c;
int i;
}u1;
u1.i = 1;
return u1.c;
}
int main()
{
int ret = check_sys();
if (1 == ret)
printf("小端\n");
else
printf("大端\n");
return 0;
}
联合的大小至少是最大成员的大小
当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍。
union Un1
{
char c[5];
int i;
};
union Un2
{
short c[7];
int i;
};
int main()
{
printf("%d\n", sizeof(union Un1));
printf("%d\n", sizeof(union Un2));
return 0;
}
cs