本章重点
深入了解结构体、枚举、联合
结构体
结构是一些值的集合
//结构体类型声明
struct tag //tag结构体的标签
{
char name[20];
int age;
}student; //student是结构体变量,也是全局变量
int main()
{
struct tag student = { "zhangsan",18 };
return 0;
}
匿名结构体类型
struct
{
char name[20];
int age;
}s1,*ps;
int main()
{
ps=&s1;
return 0;
}
//会报警告
结构自引用
typedef struct Node //重定义
{
int data;
struct Node* n; //自引用
}Node;
int main()
{
return 0;
}
结构体的初始化
结构体的内存对齐
//头文件
#include <stddef.h>
//计算得出变量i的偏移量是4
//从变量c的起始位置向后数4个字节是变量i的其实位置
//所以计算得出S的大小是8个字节
修改默认对齐数
结构体传参
最好用指针这种方式,因为函数传参是需要压栈的
指针这种方式,参数前面最好加上const,安全一些
const struct* p
位段
1.位段的成员必须是int、unsigned int或者signed int或者char类型(整型家族的)
2.位段的成员名后边有一个冒号和数字
3.位就是二进制位
4.位段上的空间是按照int类型或者char类型的方式开辟的,一次4个字节或者1个字节
5.位段是不跨平台的
#include <stdio.h>
struct A
{
int _a : 10; //int类型开辟4个字节空间,分配10个
int _b : 20; //在分配20个
int _c : 30; //不够了在开辟4个字节的空间
//加起来就是8个字节
};
int main()
{
printf("%d\n", sizeof(struct A));
return 0;
}
位段在VS2019中是以下面这种方法保存的
位段的跨平台问题
1.int位段被当成有符号数还是无符号数是不确定的
2.位段中的最大数目不能确定(16位机器int最大16个字节,大于16会报错)
3.位段中的成员在内存中从左向右分配,还是从右向左分配尚未定义
4.当一个结构包含两个位段,第二个位段成员比较大,第一个位段剩下的位不能满足第二个位段,无法确定第一个位段剩余空间的情况
枚举
void menu()
{
printf("**************************\n");
printf("*****1.add 2.sub *****\n");
printf("*****3.mul 4.div *****\n");
printf("****** 0.exit *****\n");
printf("**************************\n");
}
enum Calc
{
EXIT, //默认是0,依次加一
ADD,
SUB,
MUL,
DIV
};
void Add()
{
int x, y;
printf("请输入两个数:");
scanf("%d %d", &x, &y);
printf("%d\n", x + y);
}
int main()
{
int input = 0;
do
{
menu();
printf("请选择:");
scanf("%d", &input);
switch (input)
{
case ADD:
Add();
break;
}
} while (input);
return 0;
}
枚举的优点
1.增加代码的可读性和可维护性
2.和#define定义的标识符比较,枚举有检查类型,更加严谨
3.防止了命名污染
4.便于调试,#define不便于调试
5.使用方便,一次可以定义多个常量
联合(共用体)
联合也是一种特殊的自定义类型,这种类型定义的变量也包含一系列的成员,特征是这些成员共用同一块空间