一.结构体
一.结构体变量定义,初始化,结构体内容的访问
首先,结构体变量的定义,需要首先搭建结构体的框架,然后定义变量,其次,对其初始化类似于数组的初始化,即初始化每一个字段的内容。
#include <stdio.h>
struct person{
char name[20];
int age;
char gender;
float height;
} hug2 = {"xiaohong", 18, 'F', 1.62};
void output(struct person *p){
printf("%s %d %c %f\n", p->name, p->age, p->gender, p->height);
return ;
}
int main() {
struct person hug = {"xiaoming", 18, 'M', 1.72};
printf("%s %d %c %f\n", hug.name, hug.age, hug.gender, hug.height);
output(&hug);
output(&hug2);
return 0;
}
上述代码中,对于结构体的访问,可以通过变量名,即hug.name一类的方式直接访问,也可以利用指针进行间接访问。
还要注意的是,除了像hug这样定义结构体变量之外,还可以通过在结构体后直接加变量名来定义,如hug2。
在第一种定义方式中,hug的类型名struct person太长,我们可以用typedef关键字来对其重命名。
#include <stdio.h>
typedef struct person{
char name[20];
int age;
char gender;
float height;
} person;
void output(struct person *p){
printf("%s %d %c %f\n", p->name, p->age, p->gender, p->height);
return ;
}
int main() {
person hug = {"xiaoming", 18, 'M', 1.72};
output(&hug);
return 0;
}
二.结构体占用内存大小
想要解决这个问题,就必须知道结构体的对齐规则。
1.类型都有对齐值,内建类型的对齐值就是其自身的大小
2.结构体的对齐值等于其成员中的最大对齐值
3.成员被存储在其整数倍的对齐值位置上
4.可以通过#pragma pack 限制对齐值的最大值
所以,像上面的结构体struct person来说,name对齐值为1,age对齐值为4,gender对齐值为1,height对齐值为4,则该结构体对齐值为4。
另外,结构体在申请内存空间时,是按其对齐值大小申请的,对于struct person来说,他先申请四个字节的空间,申请五次,存放name,然后再申请一次存放age,再申请一次存放gender,但是在这多余的三个字节中,根据第三条,无法存height,因为其对齐值为4,所以在申请一次存height,一共申请八次,即32字节,所以该结构体大小为32字节。
注意,内存空间是从0开始标记的,如第1个字节为0,第32个字节为31.
当利用#pragma pack时,结构体内成员的对齐值也会受到其限制,即,大于给定最大对齐值的成员起对齐值变为该最大对齐值,如#pragma pack(4),则对于double类型的变量其对齐值变为4
二.联合体
联合体通俗的说就是在同一片内存空间下存储不同的数据类型,他的定义与初始化与结构体相似,就不赘述,其关键字为union。
当改变联合体内部成员的数据是,其他成员在对应位置的数据也会因此改变,联合体的大小取决于其成员类型所占用的最大字节大小相同。
对于联合体的使用,日后进行补充。
三.枚举类型
枚举是 C 语言中的一种基本数据类型,用于定义一组具有离散值的常量,它可以让数据更简洁,更易读。
枚举类型通常用于为程序中的一组相关的常量取名字,以便于程序的可读性和维护性。
枚举类型的变量定义与结构体相似,其关键字为enum。
#include <stdio.h>
enum number{
zero,one,two,three,four
};
int main() {
enum number a;
a = zero;
printf("%d\n", a);
a = one;
printf("%d\n", a);
a = two;
printf("%d\n", a);
a = three;
printf("%d\n", a);
a = four;
printf("%d\n", a);
return 0;
}
对于枚举类型内部的成员,其值从0开始累加,如上述代码中枚举结果就是
0
1
2
3
4
当给其成员赋值时,在其之后的值就从该成员开始累加,例如,two = 10时,其结果为
0
1
10
11
12
那枚举类型用什么用途呢?
首先,他可以实现数组自动扩容。
可以看这篇文章。
其次,他可以增加程序的可读性和辅助程序的作用。
例如,我们想要输出彩色文字时,可以采用如下方法:
printf("\033[+参数1+:+参数2+:+参数3+m + 内容 + \033[0m");
1.通用格式控制:
0:重置所有属性
1:高亮/加粗
2:暗淡
4:下划线
5:闪烁
7:反转
8:隐藏
2.背景色:
40:黑
41:深红
42:绿
43:黄色
44:蓝色
45:紫色
46:深绿
47:白色
3.前景色
30:黑
31:红
32:绿
33:黄
34:蓝色
35:紫色
36:深绿
37:白色
#include <stdio.h>
int main() {
printf("\033[1;32;43mhello world\033[0m");
return 0;
}
但是上述方法可读性低,我们可以利用枚举类型封装字体颜色工具
#include <stdio.h>
enum color{
RED = 31,
GREEN,
YELLOW,
BLUE
};
#define COLOR_SET "\033[1;%dm"
#define COLOR_END "\033[0m"
int main() {
printf(COLOR_SET "hello world\n" COLOR_END, RED);
printf(COLOR_SET "hello world\n" COLOR_END, GREEN);
printf(COLOR_SET "hello world\n" COLOR_END, YELLOW);
printf(COLOR_SET "hello world\n" COLOR_END, BLUE);
return 0;
}