目录
结构体
匿名结构体
结构体的自引用
结构体的内存对齐
对齐规则
结构体内存对齐的原因
结构体传参
位段
位段的声明
位段如何分配内存
位段的不确定因素
联合体
联合体的声明
联合体的大小
联合体的应用
枚举
枚举的声明
枚举的使用
枚举相比于宏定义“#define”的优点
结构体
结构体生活中一类实物抽象出来的一个定义,结构体的定义和结构体变量的创建以及初始化如下:
#include<stdio.h>
struct Std//结构体的创建
{
int age;
char name[];
};
int main()
{
struct Std s1;//结构体变量的创建
s1 = {18,"zhangsan"};//结构体变量的初始化
s1.age = 22;//可单独初始化
return 0;
}
匿名结构体
顾名思义:没有名字的结构体。(一般只能使用一次)在代码中的定义如下:
#include<stdio.h>
struct
{
int a;
char b;
}x;//创建匿名结构体变量x
结构体的自引用
结构体自己引用自己叫做结构体的自引用,(和二叉树的原理相似)在代码中的使用如下:
#include<stdio.h>
struct Std
{
int a;
struct Std* next;//将下一个同类型的结构体指针作为成员放在结构体中
};
结构体的内存对齐
对齐规则
PS:函数“offsetof(类型,成员)”可以测试出成员地址和结构体起始地址之间的偏移量
结构体内存对齐的原因
#include<stdio.h>//两个成员完全相同(顺序不同)的结构体,因为内存对齐造成结构体的内存大小不同
struct Std1
{
char a;
int b;
char c;
};
struct Std2
{
char a;
char b;
int c;
};
int main()
{
printf("%zu\\n",sizeof(struct Std1));//12
printf("%zu\\n", sizeof(struct Std2));//8
return 0;
}
- 如果既要结构体内存对齐,又要节省内存空间,在定义结构体时把内存较小类型相同的成员放到一起并放到前面;
- Windows系统下在结构体前面加上“#pragma pack()”可以改变编译器的默认对齐数(最好改为2的次方数)。
结构体传参
结构体传参分为两种方式:
结构体变量传参
#include<stdio.h>
struct Std1
{
char a;
int arr[20];
};
void my_print(struct Std1 s)
{
s.a = '7';
printf("%c\\n", s.a);
}
int main()
{
struct Std1 s1 = { 0 };
my_print(s1);
return 0;
}
结构体指针传参
#include<stdio.h>
struct Std1
{
char a;
int arr[20];
};
void my_print(struct Std1* s)
{
s->a = '7';
printf("%c\\n", s->a);
}
int main()
{
struct Std1 s1 = { 0 };
my_print(&s1);
return 0;
}
位段
位段的声明
位段的声明的和结构体的声明相似,只有两点不同:
struct Std
{
int a : 2;
int b : 5;
};
这就是一个完整位段的声明。
位段如何分配内存
位段的不确定因素
PS:
- 与结构体相比,位段可以达到相同效果,可以节省内存空间,但是存在平台问题(应用于网络协议中)
- 内存的最小单元为1个字节,但是在位段中一个字节中可以有几个成员存储,因此位段中的成员不能使用取地址符(&)取地址,也不能使用scanf()进行输入。
联合体
联合体像结构体一样,可由一个或多个成员构成,这些成员可以是不同类型,但是编译器只为占内存最大的成员分配足够的内存空间,所有的成员共用一个内存空间,所以联合体有另一个名字:共用体。
联合体的声明
除了关键字换为:union,其余声明方式与结构体一致。
union Un
{
int a;
char b;
};
由于联合体的所有成员共用一块内存,因此同一时间只能调用一个成员。
联合体的大小
union Un
{
char a[5];
int b;
};
int main()
{
printf("%zu\\n", sizeof(union Un));//最大成员内存为5,但是最整个联合体的内存为:8
return 0;
}
联合体的应用
- 成员存在同一时间只用一个的情况;
- 用于判断系统的大、小端字节序存储;
- 和结构体嵌套使用。
union Un
{
char a;
int b;
};
int main()//VS环境下为:小端存储
{
union Un un;
un.b = 1;
if (un.a == 0)
{
printf("大端存储");
}
else
{
printf("小端存储");
}
return 0;
}
枚举
把可能的值一一列举。
枚举的声明
enum SEX
{
MALE,
FEMALE,
SECRET
};
列举的每种情况之间用逗号隔开,若没有特殊赋值,系统会默认给第一个赋值“0”,后续的依次加一,枚举的每种情况都有对应的值。(声明时可以给每一种情况赋特殊值)
枚举的使用
enum SEX sex = MALE;//把其中一种情况赋值
网硕互联帮助中心






评论前必须登录!
注册