赞
踩
结构体(struct)是由一系列具有相同类型或不同类型的数据构成的数据集合,也叫结构。是一种聚合类型,里面可以包含多种数据类型,甚至可以结构体里嵌套结构体。相信我,等你深入理解了C言语之后,结构体在C语言里是一个神器。
C语言有五种基本数据类型:字符(char)、整型(int)、单精度实型(float)、双精度实型(double)和空类型(void)。
C语言还提供了几种聚合类型(aggregate types),包括数组、指针、结构体(struct)、共用体(联合)、位域和枚举。
结构体(Structure)是一个或多个相同数据类型或不同数据类型的变量集合在一个名称下的用户自定义数据类型。struct 结构体名,成员列表。
因为有typedef关键字,PER实际上也就是结构体类型名,用PER可以直接定义变量。结构体定义的格式是struct 结构体名。
1.结构体的设计
struct Student{
成员列表;
}
这里需要注意的是,在c++的编译环境下,后续想要使用结构体可以直接用Student
但是在c语言中,就不能直接使用,我们可以结合之前使用的typedef对结构体进行重定义,那么他在c和c++中都可以直接使用Student
例如
typedef struct Student{
成员列表;
}Student;
那么这不论在什么编译环境下都可以直接使用Student进行结构体的使用
2.结构体的使用和成员的访问
1) Student s ={成员列表赋值};
s.成员 . 成员访问符
2) Student s = {赋值};
PStu p = &s;
(*p).成员
p->成员
在给结构体的成员进行赋值之后,我们可以通过指针指向再解引用的方式访问成员,或者使用结构体中的特殊符号->对成员进行访问,例如
(*p).name 这就可以访问结构体中的成员的name元素
3.结构体和指针的结合
Student arr[]={{成员赋值},{成员赋值}};
这样就可以一次对多个成员进行赋值
- typedef struct Student Student;
- typedef struct Student* PStu;
- //等价于下方 类型的重命名
-
-
- typedef struct Student {
- const char* name;
- int age;
- int score;
- }Student, * PStu;
-
- int main() {
- Student s = {"zs",10,100};
- // s.name;
- //结构体和指针结合
- //struct Student* ptr = &s;
- PStu ptr = &s;
- printf("%s\n",(*ptr).name); //1
- printf("%s\n",ptr -> name); //2 1 2 效果相同 -> 指向符具有解引用功能
- }
- int main() {
- //定义一个结构体变量, . 成员访问符
- struct Student stu = { "zs",10,100 };
- struct Student stu2;
- stu2 = { "lisi",9,99 };
- //通过结构体变量来进行成员的访问:
- printf("%s\n", stu.name);
-
- //定义一个结构体类型的数组,赋值,数据打印:第..个学生姓名,年龄
- //struct Student arr[] = { {"zs",10,100},{"lisi",9,99},{"ww",8,88}};
- struct Student arr[] = { stu,stu2,{"ww",8,88} };
- int len = sizeof(arr) / sizeof(arr[0]);
- for (int i = 0; i < len; i++) {
- printf("第%d个学生:姓名:%s 年龄:%d\n", i + 1, arr[i].name, arr[i].age);
- }
-
- }
这里就是结构体与指针的结合,就可以用指针的解引用或者结构体的特殊符号访问到成员中的元素。
//typedef struct Student {
// const char* name;
// int age;
// int score;
//}Student, * PStu;
这里就重定义了一个指针类型 PStu,那么后面想要定义一个结构体类型的指针变量就可以直接使用Pstu进行定义
4.结构体的嵌套使用
- struct Time { //声明结构体 Time
- int hh; //时
- int mm; //分
- int ss; //秒
- };
- struct Birthday { //声明结构体 Birthday
- int year;
- int month;
- int day;
- struct Time dateTime //嵌套结构
- };
还可以进行多重嵌套使用
- struct Time { //声明结构体 Time
- int hh; //时
- int mm; //分
- int ss; //秒
- };
- struct Birthday { //声明结构体 Birthday
- int year;
- int month;
- int day;
- struct Time dateTime //嵌套结构
- };
- struct Student { //声明结构体 Student
- char name[20];
- int num;
- float score;
- struct Birthday birthday; //嵌套结构
- }
那么我们可以使用结构体进行一个成绩排名系统,那么就设计到了结构体的定义,结构体的赋值,以及结构体和指针的结合的形式访问结构体内部元素的的功能
我们要求对成绩进行冒泡排序,并且成绩相同时按姓名排序
那么我们可以提前得到一些结论 ,在使用冒泡排序和交换元素时,我们传递的数组和元素类型是不相同的,那么我们如何统一这些变量呢,我们可以使用if语句判断,但是这大大提高了代码运行时间,因此我们采用定义一个任意类型的变量
typedef Student ElemType;这样在传递参数是,可以用ElemType直接作为类型
然后还要对交换元素进行修改,要想通过形参的改变引起实参的改变,我们可以使用指针来访问元素,在交换函数运行完后,申请的栈内存空间消失后,任然可以该改变实际参数,这样就完成了两元素的交换
其次在冒泡排序时,应该考虑到多种情况,如果成绩不同,那么可以直接进行冒泡排序,如果成绩相同,我们则要改为再对名字进行比较,这里我们就可以使用系统提供的strcum对名字进行比较,然后调换位置,最后实现对包含成绩的结构体进行排序。
具体代码
- typedef struct Student {
- const char* name;
- int score;
- int age;
- }Student;//结构体的定义
-
- typedef Student ElemType;
-
- void Swap(ElemType* a, ElemType* b) {
- ElemType temp = *a;
- *a = *b;
- *b = temp;
- }//传入指针的交换函数
- //不同类型的一维数组
- void BubbleSort(ElemType* arr, int len) {
- int flag = 0;
- for (int i = 0; i < len; i++) { //趟数
- flag = 0;
- for (int j = 0; j < len - 1 - i; j++) {
- if (arr[j].score > arr[j + 1].score) {
- Swap(&arr[j], &arr[j + 1]);
- flag = 1;
- } //成绩相同,按照姓名 降序排序
- else if (arr[j].score == arr[j + 1].score) {
- if (strcmp(arr[j].name, arr[j + 1].name) < 0) {
- Swap(&arr[j], &arr[j + 1]);
- }
- }
- }
- if (!flag)
- break;
- }
- }
-
- int main() { // ww zs lisi
- Student arr[] = {
- {"lisi",100,9},{"zs",100,10},{"ww",88,9}
- }; // 1 2 3 4
- int len = sizeof(arr) / sizeof(arr[0]);
- BubbleSort(arr, len);
- for (int i = 0; i < len; i++) {
- printf("%s %d\n",arr[i].name,arr[i].score);
- }
-
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。