C语言知识点 – 结构体、枚举
一、结构体
1.结构体成员访问
1.用结构体变量访问
结构体变量 . 结构体成员
struct Stu
{
char name[10];
int age;
};
void Print(struct Stu s)
{
printf("%s\n", s.name);
printf("%d\n", s.age);
}
int main()
{
struct Stu s1 = {"zhangsan", 24};
Print(s1);
return 0;
}
2.用结构体指针访问
结构体指针 -> 结构体成员
struct Stu
{
char name[10];
int age;
};
void Print(struct Stu* ps)
{
printf("%s\n", s->name);
printf("%d\n", s->age);
}
int main()
{
struct Stu s1 = {"zhangsan", 24};
Print(&s1);
return 0;
}
2.结构体传参
结构体传参时,要传结构体的地址
3.结构体的特殊声明
匿名结构体的声明
代码如下:
struct
{
int a;
char b;
float c;
}u;//匿名结构体后面必须声明变量,只能用一次
struct
{
int a;
char b;
float c;
}*p;
int main()
{
p = &u;//匿名结构体的内容虽然是一样的,但编译器还是会将他们看成不同的两个类型的结构体,因此是非法的
return 0;
}
4.结构体的自引用
代码如下:
//struct Node
//{
// int a;
// struct Node next;
//};//无法确定结构体占内存大小,错误
typedef struct Node
{
int a;//数据域
struct Node* next;//正确方式应该写成结构体指针类型 指针域
//而且必须将结构体名字写全,前面有struct
}Node;
5.结构体内存对齐
计算结构体占用空间大小时,需要考虑结构体的内存对齐,其原则如下:
1.第一个成员在与结构体偏移量为0的地址处;
2.其他成员变量应对齐到对齐数的整数倍的地址处,
对齐数 = 编译器默认对齐数和该成员大小的较小值(vs默认对齐数为8byte);
3.结构体大小为最大对齐数的整数倍(每个成员变量都有一个对齐数,不包含默认对齐数);
4.若存在结构体嵌套,则嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体大小就是最大对齐数的整数倍。
例如:
struct S1
{
char c1;//对齐到偏移量0,占1字节
int i;//对齐数为4,对齐到偏移量4,占4字节
char c2;//对齐数为1,对齐到偏移量9
};//最大对齐数为4,总大小为12字节
struct S2
{
char c1;//对齐到偏移量0,1字节
char c2;//对齐数为1,对齐到偏移量1,1字节
int i;//对齐数为4,对齐到偏移量4,4字节
};//最大对齐数为4,总大小8字节
struct S3
{
double d;//对齐到偏移量0,8字节
char c;//对齐数为1,对齐到偏移量8,1字节
int i;//对齐数为4,对齐到偏移量12,4字节
};//最大对齐数为8,总大小16字节
struct S4
{
char c1;//对齐到偏移量0,1字节
struct S3 s3;//S3最大对齐数为8,对齐到偏移量8,16字节(8 -> 23)
double d;//对齐数为8,对齐到偏移量24,8字节
};//最大对齐数为8,总大小32字节
6.修改默认对齐数
代码如下:
//修改默认对齐数
#pragma pack(1)//设置默认对齐数为1
struct S5
{
char c1;
int i;
char c2;
};//由于修改默认对齐数,S5总大小为6字节
#pragma pack()//还原默认对齐数为8
二、枚举
1.定义
enum Day
{
Mon,//值从0开始,依次递增
Tues,
Wes,
Thur,
Fri,
Sat,
Sun
};
enum Color
{
RED = 5,//也可以在定义时初始化
GREEN = 10,
BLUE = 15
};
int main()
{
enum day1 = Mon;
enum c1 = RED;
return 0;
}