本篇是C语言高级部分的收尾笔记,将主要整理结构体,联合体以及枚举的相关知识点。
如需C语言基础部分的知识点,请点击 C语言学习笔记(上)-CSDN博客C语言学习笔记(中)-CSDN博客、C语言学习笔记(下)-CSDN博客、C语言基础补充知识点-CSDN博客、C语言高级部分请看C高级学习笔记(上)-CSDN博客、C高级学习笔记(中)-CSDN博客以及本篇文章,如果有不明白的请私信博主,我一定知无不言。当然,有任何不对的地方还请大家批评指正。
C语言属于面向过程的一门语言,但是使用时需要有着对象的思想,C语言表示对象的方式就是结构体类型。
结构体属于C语言中的一个自定义的构造函数,关键字(struct),将很多不同的数据类型封装成一个新的数据类型,这个数据类型就是结构体类型,结构体中的成功在内存空间中连续的,并且每个成员都有其独立的内存空间。
利用结构体描述一个对象:
struct student{ //声明一个结构体类型,此时struct student就表示一个结构体类型名,
//使用此类型可以定义结构体类型的变量
char name[20];
int age;
int score;
};
//定义一个对象
struct student stu;
//定义10个对象
struct student stu_arr[10];
声明一个结构体类型,此时并没有在内存中分配空间。
struct 结构体{
数据类型 成员变量名1;
数据类型 成员变量名2;
……
数据类型 成员变量名n;
};
上述格式中“struct 结构体名”就是自定义的结构体类型,使用此结构体类型定义结构体类型的变量。结构体中的成员的类型可以是:基本的数据类型,数组类型,指针类型,指针数组,数组指针,函数指针,函数指针数组,嵌套的结构体类型,枚举类型,联合体类型。
struct 结构体名 结构体变量名;
struct 结构体名 *结构体指针变量名
结构体变量名.成员变量名;
结构体指针变量名 -> 成员变量名;
采用上述的声明结构体类型的方法,以及定义结构体类型的变量的方式进行操作后,需要对结构体中的成员进行初始化
初始化的方式有两种:1.定义结构体类型变量的同时进行初始化。2.先定义结构体类型的变量,后进行初始化的操作
展示如下:
1、定义的同时进行初始化:struct student stu = {“xiaobai” ,24,100};
2、先定义后初始化:
struct student stu;
strcpy(stu.name,“xiaobai”);
stu.age = 24;
stu.score = 100;
3.扩展:同样的定义结构体类型变量的同时进行初始化还有下面的这种操作
struct student stu = {.name = "xiaobai",
.age = 24,
.sorce = 100
};这种方式的好处是,可以只对结构体中的部分成员进行初始化的操作
struct student{
char name[20];
int age;
int score;
}stu1,stu2,stu3;
struct student{
char name[20];
int age;
int score;
}stu1={"xiaobai",24,100};
struct student{
char name[20];
int age;
int score;
}stu2 = {
.name = "xiaobai",
.age = 24,
.score = 100};
struct student{
char name[20];
int age;
int score;}stu3;
strcpy(stu3.name, "xiaobai");
stu3.age = 24;stu3.score = 100;
注意:当声明结构体变量类型的时候省略了结构体的名字,只能在声明结构体类型的同时定义结构体类型的变量,并且后续不能在用这个结构体类型定义新的变量。
采用上述的声明结构体类型的方法以后,定义结构体指针变量
struct student *p;
struct student stu = {"xiaobai",24,100};
//第一种定义方法
struct student *p = &stu;
//第二中定义方法
struct student *p = NULL;
p = &stu;
struct student *p = (struct student *)malloc(sizeof(struct student));
strcpy(p -> name, "xiaobai");
p -> age = 24;
p ->score = 100;
struct student {
char *name;
int *age;
};
int myage = 24;
struct student stu ={"xiaobai", &myage}; // 此时char *name指向的是一个字符串变量
//int *age 指向一个int 类型的变量
char myname[20]= "xiaobai";
int myage = 18;
struct student stu = {myname, &myage}; //此时 char *name指向的是一个字符数组
// int *age 指向的一个int类型的变量
struct student stu;
stu.name = (char *)malloc(sizeof(char)*20); // char *name成员指向堆区空间
stu.age = (int *)malloc(sizeof(int)); // int *age成员指向堆区空间
采用声明普通结构体类型的方式,定义结构体数组变量 : struct student 结构体数组名[数组的长度];
struct student arr[2];
struct student arr[2] = {{"xiaobai",24,100},{"saodiseng",24,90}};
struct student arr[2] = {
[0] = {
.name = "xiaobai",
.age = 24,
.score = 100
},[1] = {
.name = "saodiseng",
.age = 24,
.score = 90
}};
struct student arr[2];
strcpy(arr[0].name, "xiaobai");
arr[0].age = 24;
arr[0].score = 100;
strcpy(arr[1].name, "saodiseng");
arr[1].age = 24;
arr[1].score = 90;
结构体指针数组的本质其实就是数组,数组中的成员是结构体指针
struct 结构体名 *结构体指针数组名[元素个数];
struct 结构体名 *结构体指针数组名[元素个数] = {&结构体变量0, &结构体变量1};
struct 结构体名 *结构体指针数组名[元素个数];
结构体指针数组名[下标] = &结构体变量0;
结构体指针数组名[下标] = &结构体变量1;
结构体数组指针就是一个指针,指向的是一个结构体二维数组
struct 结构体名 (*结构体数组指针名)[元素个数];
struct 结构体名 结构体数组名[元素个数] = {{},{},.....};
struct 结构体名 (*结构体数组指针名)[元素个数] = &结构体数组名;
struct 结构体名 (*结构体数组指针名)[元素个数];
结构体数组指针名 = &结构体数组名;
(*结构体数组指针名)[下标].结构体成员名;
((*结构体数组指针名)+下标)->结构体成员名;
struct student
{
char name[20];
int age;
int score;
};
struct student stu1 = {"xiaobai", 24, 100};
struct student stu2 = stu1; // 普通结构体变量进行赋值
struct student *p = NULL; // 结构体指针变量进行赋值
*p = &stu1;
struct student *p2 = p; // 结构体指针变量进行赋值
struct 结构体名{
返回类型 (*函数指针名)(形参列表);
}
struct 结构体名 结构体变量名;
结构体变量名.函数指针名 = 函数名;
结构体变量名.函数指针名(实参列表);
typedef struct /*结构体名*/{
数据类型 成员变量名0;
……
}结构体类型的别名;
结构体类型的别名 普通结构体变量名;
结构体类型的别名 *结构体指针变量名;
typedef struct 结构体名{
struct 结构体名1 结构体变量名1;
struct 结构体名2 *结构体指针变量名1;
}结构体别名;
结构体别名 普通结构体别名;
普通结构体变量名.结构体变量名1.成员名;
普通结构体变量名.结构体指针变量名1 ->成员名;
结构体别名 *结构体指针变量名;
结构体指针变量名->结构体变量名1.成员名;
结构体指针变量名->结构体指针变量名1->成员名;
联合体属于构造类型,联合体中可以包含不同的数据类型的成员,联合体中的所有的成员共用同一块内存空间,
注意:联合体类型的大小和联合体中最大的成员的大小一致。
typedef union 联合体名{
数据类型 成员名1;
数据类型 成员名2;
……
}联合体别名;
联合体别名 普通联合体变量名
联合体别名 *联合体指针变量名
普通联合体变量名.成员变量名 = 初始值;
联合体指针变量名->成员变量名 = 初始值;
普通联合体变量名.成员变量名;
联合体指针变量名->成员变量名;
枚举类型是一个基本类型,不属于构造类型,枚举中的成员是一个常量,默认第一个成员的对应的常量值为0.
typedef enum 枚举类型名{
成员名0,
成员名1,
成员名2,
.......} 枚举类型的别名;
3.1 枚举类型中的成员可以直接使用,不需要定义枚举类型的变量,就当成一个常量使用。
3.2 定义枚举类型的变量,必须使用枚举类型中的成员对枚举类型的变量进行初始化
枚举类型的别名_t 变量名 = 枚举类型中的成员名;
3.3 枚举类型可以作为函数的参数或者返回值
3.4 枚举类型的成员是一个常量,如果使用的是宏定义定义的常量,可以使用枚举替换。