C语言基础-结构体
结构体的现实意义
现实世界里有很多事物是由不同的部分组合起来的。例如手机由屏幕、CPU、芯片、电池等多个部分组成。同时,对于每个组件如电池又由其他细小组件组成。结构体就是把这些组件组合在一起,进行统一的访问和管理。
结构体可以理解成是对现实世界的抽象。结构体不仅可以记录不同类型的数据,而且使得数据结构是“高内聚,低耦合”,更加利于程序的阅读和理解及移植。而且结构体的存储方式可以提高CPU对内存的访问速度。
定义结构体
struct 数据类型名{
//结构体数据成员列表
};
实例1
struct student{
char * name;
char * gender;
char * mail;
int age;
};
在定义完结构体后,要声明结构体变量
- 方式1
struct Student student;
- 方式2
struct Student{
char name[10];
char * gender;
char * mail;
int age;
}stu; // 在这里增加一个变量`stu`,则`stu`为结构体变量
- 方式3
struct {
char *name;
char * gender;
char * mail;
int age;
}stu;
这种方式之后无法再继续定义变量。
结构体变量的初始化
- 结构体定义时初始化
struct Student{
char name[10];
char * gender;
char * mail;
int age;
}student = {"张三", "男", "helloworld@qq.com", 21};
- 变量定义时初始化
struct Student stu;
stu = (struct Student){
"张三",
"男",
"helloworld@qq.com",
21
};
- 单成员进行赋值
//对数组类型的数据不能直接赋值,例如stu.name = "张三";
strcpy(stu.name, "张三");
stu.age = 21;
stu.gender = "男";
结构体变量的使用
可以使用变量.成员字段来使用结构体的数据成员
strcpy(stu.name, "张三");
stu.age = 21;
stu.gender = "男";
stu.mail = "helloworld@qq.com";
printf("%s\n", stu.name);
printf("%d\n", stu.age);
printf("%s\n", stu.gender);
printf("%s\n", stu.mail);
结构体数组
- 语法定义
struct Student{
char * name;
}stu[5];
使用上与单个结构体变量相同,在数组中需要加上在数组中的下标
- 使用案例
# include <stdio.h>
# include <string.h>
struct Student{
char * name;
};
int main(){
struct Student stu[2];
stu[0] = (struct Student){"张三"};
printf("%s\n", stu[0].name);
return 0;
}
- 结构体指针
指向结构体类型的指针
- 使用案例
# include <stdio.h>
# include <string.h>
struct Student{
char * name;
};
int main(){
struct Student stu = {"张三"};
struct Student *p;
p = &stu;
printf("%s\n", (*p).name);
printf("%s\n", p->name);
return 0;
}
结构体嵌套
一个结构体当中可以包含其他类型的结构体,结构体自身当中不能包含相同类型的结构体,但是可以包含执行自身的指针
- 使用案例
# include <stdio.h>
# include <string.h>
struct gender{
char * ch;
};
struct Student{
char * name;
struct Student * s;
struct gender gen;
};
int main(){
struct gender gen = {"男"};
struct Student stu = {"张三"};
struct Student student = {
"张三",
& stu,
gen
};
printf("%s\n",student.name);
printf("%s\n",(student.s)->name);
printf("%s\n",student.gen.ch);
return 0;
}
结构体变量在作为参数传递的时候使用的是值传递
typedef struct 与struct的区别
typedef关键字可以将一种数据类型添加一种别名,例如typedef int Int,此时Int等价于int。在struct中,定义的别名可以直接用于定义变量,等价于struct类型名
- 使用案例
# include<stdio.h>
# include <string.h>
struct gender {
char * ch;
};
typedef struct Student{
char *name;
struct Student * s;
struct gender gen;
}Stu;
int main(){
struct gender gen = {"男"};
struct Student stu = {"张三", NULL};
struct Student student = {
"张三",
&stu,
gen
};
// 使用新定义的类型名定义指针变量,等价于struct Student
Stu *s = &student;
printf("%s\n",(*s).name);
printf("%s\n", ((*s).s)->name);
printf("%s\n",(*s).gen.ch);
return 0;
}
enum枚举
枚举就是将我们数据可能存在的结果有限个的罗列出来,比如一个人的性别不是男就是女。
- 使用案例
# include <stdio.h>
# include <string.h>
enum Gender{
MAN = 1, //不指定值则从0开始
WOMAN = 2 //不指定值则从上一个定义的值开始递增,为2
};
int main(){
//定义枚举变量
enum Gender g;
// 枚举变量只可能存在一种值
g = WOMAN;
printf("%d\n",g);
return 0;
}
union共用体
共用体内部可以定义N个变量,但是这
N个变量之间会相互影响。共用体的所有成员占用同一段内存,修改一个成员会影响其余所有成员
- 使用案例
# include <stdio.h>
# include <string.h>
union Data{
int a;
char b;
short c;
};
int main(){
union Data d;
d.a = 46;
printf("%d\n",d.a);
printf("%c\n",d.b);
printf("%d\n",d.c);
printf("%%%%%%%%%%%%%%%%%%%%%%%%%%\n");
d.b = 'a';
printf("%d\n",d.a);
printf("%c\n",d.b);
printf("%d\n",d.c);
printf("%%%%%%%%%%%%%%%%%%%%%%%%%%\n");
d.c = 47;
printf("%d\n",d.a);
printf("%c\n",d.b);
printf("%d\n",d.c);
return 0;
}
结果显示:
46
.
46
%%%%%%%%%%%%%
97
a
97
%%%%%%%%%%%%%
47
/
47