本文首发自「慕课网」,想理解更多 IT 干货内容,程序员圈内热闻,欢送关注 ” 慕课网 ”!
作者:张磊 | 慕课网讲师
0 根底学员在通过 C 语言根底语法的学习后,须要通过一些实战案例来学习如何将 C 语言利用到理论工作中,明天咱们通过一个学生管理系统案例的开发来晋升理论开发能力。
1. 零碎介绍
在这里,咱们首先采纳了数组的形式来存储咱们输出的内容。同时,咱们这里利用里后面学习到的 struct 来结构化存储咱们的学生信息。
咱们实现了根本的对于数据操作的几项性能:增、删、改、查。
也就是咱们能够向这个零碎中增加数据,删除数据,批改数据,还有就是查问数据。这里的查问数据,咱们又分为了全副无条件的查问,和依照姓名条件的查问。
2. 性能
零碎的性能外面咱们设计了增加、删除、批改、列表显示和查问等 5 个性能。
增加:增加就是将数据增加到存储数据的数组中;
删除:删除就是依据指定的序列号删除特定的一条数据;
批改:批改就是依据指定的序列号来批改学生的问题;
列表显示:列表的显示,其实就是无条件的查问,也就是在没有特点查问条件的状况下,将存储的数据全副显示进去;
查问:这里的查问,就是依照姓名这个个性的条件。把合乎这个条件的数据筛选进去,并显示进去。
3. 示例程序
#include <stdio.h>
#include <string.h>
#define StudentNumbers 50
#define NameLength 50
typedef struct
{
int id;
char name[NameLength];
int age;
int score;
int flag;
} Student;
int add(Student student, Student Students[]);
int del(int id, Student students[]);
int display(Student students[]);
int update(int id, Student students[]);
int search(char name[], Student students[]);
int main()
{
int id = -1;
char name[NameLength];
int choice = 0;
int stop = 0;
Student students[StudentNumbers];
Student student;
for (int i = 0; i < StudentNumbers; i++)
{students[i].id = i;
students[i].flag = 0;
}
while (stop == 0)
{printf("-------------------------\n");
printf("* 学生管理系统 *\n");
printf("-------------------------\n");
printf("1 增加 \n");
printf("2 批改问题 \n");
printf("3 查问 \n");
printf("4 删除 \n");
printf("5 显示学生列表 \n");
printf("0 退出程序 \n");
printf("请间接输出数字选项:");
scanf("%d", &choice);
switch (choice)
{
case 1:
printf("请输出学生姓名:");
scanf("%s", student.name);
printf("请输出学生的年龄:");
scanf("%d", &student.age);
printf("请输出学生问题:");
scanf("%d", &student.score);
add(student, students);
break;
case 2:
printf("请输出要批改问题的学生编号:");
scanf("%d", &id);
update(id, students);
break;
case 3:
printf("请输出要查找的学生姓名:");
scanf("%s", name);
search(name, students);
break;
case 4:
printf("请输出要删除的学生编号:");
scanf("%d", &id);
del(id, students);
break;
case 5:
display(students);
break;
case 0:
stop = 1;
break;
default:
printf("输出选项有误 \n");
break;
}
}
return 0;
}
int add(Student student, Student students[])
{for (int i = 0; i < StudentNumbers; i++)
{if (students[i].flag == 0)
{strcpy(students[i].name, student.name);
students[i].age = student.age;
students[i].score = student.score;
students[i].flag = 1;
return 0;
}
}
return 1;
}
int del(int id, Student students[])
{for (int i = 0; i < StudentNumbers; i++)
{if (students[i].id == id)
{students[i].flag = 0;
return 0;
}
}
return 1;
}
int display(Student students[])
{printf("******************\n");
printf("学生列表 \n");
printf("******************\n");
for (int i = 0; i < StudentNumbers; i++)
{if (students[i].flag == 1)
{printf("学生编号:%d,学生姓名:%s,年龄:%d,问题:%d\n", students[i].id, students[i].name, students[i].age, students[i].score);
}
}
printf("******************\n");
return 0;
}
int update(int id, Student students[])
{
int score = -1;
printf("请输出新的问题:");
scanf("%d", &score);
for (int i = 0; i < StudentNumbers; i++)
{if (students[i].id == id)
{students[i].score = score;
return 0;
}
}
return 1;
}
int search(char name[], Student students[])
{for (int i = 0; i < StudentNumbers; i++)
{if (strcmp(name, students[i].name) == 0)
{printf("学生编号:%d,学生姓名:%s,年龄:%d,问题:%d\n", students[i].id, students[i].name, students[i].age, students[i].score);
return 0;
}
}
printf("没有查找到相干学生信息。\n");
return 1;
}
很多人可能会第一次接触这么长的程序,会产生畏惧的心理。其实不必放心。要置信本人能够看懂的。
咱们离开来解说一下。
在程序的最开始咱们须要引入程序中可能须要应用的函数的头文件。这里咱们因为要应用 printf、scanf 等,所以须要 stdio 函数库。因为要应用 strcpy、strcmp 函数,所以须要 string 函数库。
#include <stdio.h>
#include <string.h>
为了便于程序中的保护,不必在很多出批改共用的数值。所以这里定义了一个常量
#define StudentNumbers 50
#define NameLength 50
为了存储学生的信息。咱们用了 struct 来定义学生的信息。外面蕴含学生的编号 id,姓名 name 这是一个字符串,年龄 age,问题 score,标记位 flag 这个变量是用来示意是否有学生信息存储在该地位的。不过这里咱们应用了之前没有介绍的一个 typedef。这个关键字应用的益处是使得前面应用这个 struct 的时候不必每次都用关键字 struct 来定义,只有用这个构造的名称间接定义就能够了,如同咱们定义整数等内置类型一样不便。
typedef struct
{
int id;
char name[NameLength];
int age;
int score;
int flag;
} Student;
为了便于保护,咱们没有依照函数呈现的程序来写。不过 C 语言始终秉承着先定义再应用的准则。所以。如果你应用的函数没有在应用前呈现,而是在前面的话,那么你就须要先让编译器晓得这个函数的根本状况。这个时候咱们会先把函数的定义写在后面。
咱们能够看到上面咱们定义了这个零碎的性能。每个性能咱们都会写一个函数。其实不写这些函数,把所有的性能写在 main 函数外部也是能够的。然而这样会在保护上存在问题。进行测试也会变得艰难。
int add(Student student, Student Students[]);
int del(int id, Student students[]);
int display(Student students[]);
int update(int id, Student students[]);
int search(char name[], Student students[]);
这里定义了一些须要应用的变量。stop 变量是用来控制程序循环的,也就是控制程序在什么时候能够完结循环的。咱们定义了一个 Student 的数组,用来存储学生的信息。用一个独自的变量来存储单条的学生信息。
int id = -1;
char name[NameLength];
int choice = 0;
int stop = 0;
Student students[StudentNumbers];
Student student;
这里咱们通过循环来初始化咱们的数组。
for (int i = 0; i < StudentNumbers; i++)
{students[i].id = i;
students[i].flag = 0;
}
循环语句如果在不扭转条件的状况下会始终循环。确保咱们的零碎能够始终运行。
while (stop == 0)
在接管到输出后。咱们就会通过 switch 来进行相应的匹配。实现对应的操作。这比应用大量的 if 语句简洁了很多。
switch (choice)
在子程序中,也就是实现增、删、改、查这些性能程序中。咱们用了循环语句来拜访数组中的元素。同时,利用了判断语句与特定的变量,来判断该地位是否存有学生信息。
运行后果:
utopia@DESKTOP:~$ ./test
-------------------------
* 学生管理系统 *
-------------------------
1 增加
2 批改问题
3 查问
4 删除
5 显示学生列表
0 退出程序
请间接输出数字选项:1
请输出学生姓名:张三
请输出学生的年龄:22
请输出学生问题:100
-------------------------
* 学生管理系统 *
-------------------------
1 增加
2 批改问题
3 查问
4 删除
5 显示学生列表
0 退出程序
请间接输出数字选项:1
请输出学生姓名:李四
请输出学生的年龄:21
请输出学生问题:90
-------------------------
* 学生管理系统 *
-------------------------
1 增加
2 批改问题
3 查问
4 删除
5 显示学生列表
0 退出程序
请间接输出数字选项:1
请输出学生姓名:王二
请输出学生的年龄:23
请输出学生问题:99
-------------------------
* 学生管理系统 *
-------------------------
1 增加
2 批改问题
3 查问
4 删除
5 显示学生列表
0 退出程序
请间接输出数字选项:5
******************
学生列表
******************
学生编号:0,学生姓名:张三,年龄:22,问题:100
学生编号:1,学生姓名:李四,年龄:21,问题:90
学生编号:2,学生姓名:王二,年龄:23,问题:99
******************
-------------------------
* 学生管理系统 *
-------------------------
1 增加
2 批改问题
3 查问
4 删除
5 显示学生列表
0 退出程序
请间接输出数字选项:2
请输出要批改问题的学生编号:1
请输出新的问题:80
-------------------------
* 学生管理系统 *
-------------------------
1 增加
2 批改问题
3 查问
4 删除
5 显示学生列表
0 退出程序
请间接输出数字选项:5
******************
学生列表
******************
学生编号:0,学生姓名:张三,年龄:22,问题:100
学生编号:1,学生姓名:李四,年龄:21,问题:80
学生编号:2,学生姓名:王二,年龄:23,问题:99
******************
-------------------------
* 学生管理系统 *
-------------------------
1 增加
2 批改问题
3 查问
4 删除
5 显示学生列表
0 退出程序
请间接输出数字选项:4
请输出要删除的学生编号:1
-------------------------
* 学生管理系统 *
-------------------------
1 增加
2 批改问题
3 查问
4 删除
5 显示学生列表
0 退出程序
请间接输出数字选项:5
******************
学生列表
******************
学生编号:0,学生姓名:张三,年龄:22,问题:100
学生编号:2,学生姓名:王二,年龄:23,问题:99
******************
-------------------------
* 学生管理系统 *
-------------------------
1 增加
2 批改问题
3 查问
4 删除
5 显示学生列表
0 退出程序
请间接输出数字选项:1
请输出学生姓名:张五
请输出学生的年龄:20
请输出学生问题:70
-------------------------
* 学生管理系统 *
-------------------------
1 增加
2 批改问题
3 查问
4 删除
5 显示学生列表
0 退出程序
请间接输出数字选项:5
******************
学生列表
******************
学生编号:0,学生姓名:张三,年龄:22,问题:100
学生编号:1,学生姓名:张五,年龄:20,问题:70
学生编号:2,学生姓名:王二,年龄:23,问题:99
******************
-------------------------
* 学生管理系统 *
-------------------------
1 增加
2 批改问题
3 查问
4 删除
5 显示学生列表
0 退出程序
请间接输出数字选项:3
请输出要查找的学生姓名: 张五
学生编号:1,学生姓名:张五,年龄:20,问题:70
-------------------------
* 学生管理系统 *
-------------------------
1 增加
2 批改问题
3 查问
4 删除
5 显示学生列表
0 退出程序
请间接输出数字选项:
在程序中,咱们首先增加了 3 条学生的记录。而后咱们进行了列表显示。接着,咱们尝试批改了其中一个学生问题,并再次查看列表,发现问题批改失效了。而后,咱们删除了一个学生,列表显示后果其曾经被删除了。而后咱们又尝试增加了一个学生。列表显示后果增加胜利。最初咱们依照姓名查找了一个学生。
4. 小结
在这里,咱们实现了一个靠近理论可用的零碎。当然作为一个能够应用的零碎,咱们还会设计到数据输出时合法性的校验,以及数据长久化的存储等等一系列的问题须要思考。
同时在一个零碎规模变大当前,其存储的构造和形式会影响到数据的操作效率,最直观的就是实现一次操作所须要的工夫会产生较大甚至微小的变动。这个时候,通过改善数据结构与算法会起到十分重大的作用。然而切记实现性能在很多时候时一个零碎的第一要务,而优化零碎则是在你实现一个零碎当前在做的事件。
学习没有起点,人生短暂而漫长。须要你一直的通过学习来找寻乐趣。不然这短暂的人生昙花一现,这漫长的人生会让你苦闷不堪。所以闲来没事,用多种形式多学习一点。
欢送关注「慕课网」帐号,咱们会始终保持内容原创,提供 IT 圈优质内容,分享干货常识,大家一起独特成长吧!
本文原创公布于慕课网,转载请注明出处,谢谢合作