1.基础
2.试题
3.实现
4.演示
基于之前的C语言内容补充三点:
栈区的结构体数组:
struct Student stu[5]={{},{},{},{},{}}; //结构体内容此处省略
堆区的结构体数组:
struct Student* p = (struct Student*)calloc(5, sizeof(struct Student));
二者的区别:
栈区的结构体数组可以直接赋值与调用,堆区的结构体数组通过指针访问。
之前讲到栈区读取速度快,但缺点在于内存较小,以Linux系统为例,栈区大小仅有8M,而堆区由于需要通过指针访问,速度较慢,但优点在于内存大,同样Linux为例,堆区有2G到3G的大小。
此项目重要通过堆区的结构体数组实现。
上文说到,堆区结构体数组内存大,但需要通过指针访问,较为缓慢。
虽然堆区的结构体数组优势不小,但栈区的结构体数组对于指针学的不好的同学以及不想使用二级指针的同学来说,在操作上会明显优于堆区的结构体数组。
因此,在下文的项目实现代码中,大家会发现在“显示所有学生信息列表”的函数实现代码中,我使用的是栈区的结构体数组。
这也给我们一个启发:栈区堆区的使用各有优缺,我们需要根据自身的需要,灵活使用。
这个比较熟悉了,有一点需要注意:
extern 变量存于静态区,用于修饰全局变量。
切记不要用extern修饰局部变量,容易出现错误。
学生管理系统:
Linux 系统 + gcc + make
学生信息:
基本数据信息:
学号: int
姓名: char 128
密码: char 32
年龄: int
班级: int
成绩信息:
数学成绩: int
C语言成绩: int
语文成绩: int
名次: int
使用终端命令界面,作为系统的输入输出界面
登录功能:
学生的账户,密码
老师的账户,密码
1.系统启动后提示登录界面。使用用户名和密码登录。学生和老师都可登录
2.用户名和密码正确登录成功,显示欢迎界面:“欢迎XX同学(老师)登录”显示操作界面
3.如果输入用户名和密码错误连续提示,超过3次自动退出
1.实现对学生信息基本信息的录入,其中名次根据成绩自动计算(添加). 学号不能重复
2.删除学生信息
3.修改学生信息
4.查找学生信息
a.根据学号查找
b.根据姓名查找
c.根据班级群体查找,把属于这个班的学生全部显示
5.显示所有学生信息列表
a.按学号顺序显示
b.按名次显示
c.按某学科(可选)成绩顺序显示,并在最后显示出此科平均分
6.退出系统
1.使用Makefile对项目进行编译
2.参考代码存放到不同文件中
3.main.c、menu.c、student.c、student.h、Makefile
1.Makefile
EXE=01_student
Objs+=main.o
Objs+=menu.o
Objs+=student.o
CC=gcc
CFlags=-c -o
all:$(EXE)
$(EXE):$(Objs)
$(CC) $^ -o $@
%.o:%.c
$(CC) $^ $(CFlags) $@
#伪目标
.PHONY:clean
clean:
rm $(EXE) $(Objs)
2.student.h
#ifndef _HEAD_H_
#define _HEAD_H_
#include
#include
#include
extern int number_of_student;
//声明结构体与别名
struct Student
{
int student_number;
char name[128];
char codes[32];
int age;
int classes;
int math;
int c_language;
int chinese;
int ranking;
};
typedef struct Student stu,*p_stu;
struct Teacher
{
int account;
char code[32];
char name[128];
};
extern struct Teacher li;
//声明函数
//menu.c
void type_in_stu(p_stu p);
void delete_stu(p_stu p);
void change_stu();
void check_stu(p_stu p);
void show_stu_list(p_stu p);
//student.c
p_stu creat_stu_list();
int judge(p_stu p);
#endif
3.student.c
#include "student.h"
//1、申请堆区空间
p_stu creat_stu_list()
{
p_stu p_1=(p_stu)calloc(7,sizeof(stu));
return p_1;
}
//2、检查账户名与密码
int judge(p_stu p)
{
int account,flag=3;
char code[32];
while(flag>0)
{
printf("请输入账户名:");
scanf("%d",&account);
printf("请您输入密码:");
scanf("%s",code);
code[strcspn(code,"\n")]='\0';
if(account==li.account && strcmp(code,li.code)==0)
{
printf("欢迎%s老师登录!\n",li.name);return 2;
}
for(int i=0;i<=number_of_student-1;++i)
{
if(account==(p+i)->student_number && strcmp(code,(p+i)->codes)==0)
{
printf("欢迎%s同学登录!\n",(p+i)->name);return 1;
}
}
flag--;
printf("登录失败,您还有%d次机会。\n",flag);
}
if(flag==0){printf("您已三次登录失败,登录页面已锁定。\n");return 0;}
}
4.menu.c
#include "student.h"
//1.录入学生
void type_in_stu(p_stu p)
{
printf("请输入学号,姓名,年龄,班级,以空格隔开:");
scanf("%d %s %d %d",&(p+number_of_student)->student_number,\
(p+number_of_student)->name,&(p+number_of_student)->age,\
&(p+number_of_student)->classes);
printf("请输入数学,c语言,语文成绩,以空格隔开:");
scanf("%d %d %d",&(p+number_of_student)->math,\
&(p+number_of_student)->c_language,\
&(p+number_of_student)->chinese);
printf("录入成功!\n");
number_of_student+=1;
}
//2.删除学生
void delete_stu(p_stu p)
{
int number,flag=0;
printf("请输入需要删除的学生的学号:");
scanf("%d",&number);
for(int i=0;i<=number_of_student-1;++i)
{
if((p+i)->student_number==number)
{
flag+=1;
for(int j=i;j<=number_of_student-1-1;j++)
{
*(p+j)=*(p+j+1);
}
printf("删除成功!\n");
number_of_student-=1;
}
}
if(flag==0)
{
printf("该学生不存在。\n");
}
}
//3.修改学生信息
void change_stu(p_stu p)
{
int number,choice,class;
char codes[32];
printf("请输入需要修改的学生的学号:");
scanf("%d",&number);
printf("请选择您要修改的信息:1.密码 2.班级:");
scanf("%d",&choice);
for(int i=0;i<=number_of_student-1;++i)
{
if((p+i)->student_number==number)
{
if(choice==1)
{
printf("请输入新密码:");
scanf("%s",codes);
strcpy((p+i)->codes,codes);
printf("修改成功!\n");
}
if(choice==2)
{
printf("请输入新班级:");
scanf("%d",&class);
(p+i)->classes=class;
printf("修改成功!\n");
}
}
}
}
//4.查找学生信息
void check_stu(p_stu p)
{
int choice,number,class,flag=1;
char name[128];
void printf_inf(int i)
{
printf("学号\t姓名\t年龄\t班级\n");
printf("%d\t%s\t%d\t%d\n",(p+i)->student_number,\
(p+i)->name,(p+i)->age,(p+i)->classes);
printf("数学\tC语言\t语文\n");
printf("%d\t%d\t%d\n",(p+i)->math,\
(p+i)->c_language,(p+i)->chinese);
}
printf("请选择查找方式:1.学号 2.姓名 3.班级:");
scanf("%d",&choice);
if(choice==1)
{
printf("请输入需要查找的学生的学号:");
scanf("%d",&number);
for(int i=0;i<=number_of_student-1;++i)
{
if((p+i)->student_number==number)
{
flag=0;
printf_inf(i);
}
}
}
else if(choice==2)
{
printf("请输入需要查找的学生的姓名:");
scanf("%s",name);
for(int i=0;i<=number_of_student-1;++i)
{
if(strcmp((p+i)->name,name)==0)
{
flag=0;
printf_inf(i);
}
}
}
else if(choice==3)
{
printf("请输入需要查找的学生的班级:");
scanf("%d",&class);
for(int i=0;i<=number_of_student-1;++i)
{
if((p+i)->classes==class)
{
flag=0;
printf_inf(i);
printf("\n");
}
}
}
else{printf("您的输入有误!");}
if(flag)printf("未找到符合条件的学生!\n");
}
//5.显示学生信息列表
void show_stu_list(p_stu p)
{
int choice, subject;
printf("请选择排序方式:\n");
printf("1.按学号顺序显示\n");
printf("2.按名次显示\n");
printf("3.按学科成绩顺序显示\n");
scanf("%d", &choice);
//将信息存入数组,方便操作
stu temp[number_of_student];
for(int i = 0; i < number_of_student; ++i)
{
temp[i] = p[i];
}
switch(choice) {
case 1: //学号
for(int i = 0; i < number_of_student-1; ++i)
{
for(int j = 0; j < number_of_student-1-i; ++j)
{
if(temp[j].student_number > temp[j+1].student_number)
{
stu t = temp[j];
temp[j] = temp[j+1];
temp[j+1] = t;
}
}
}
break;
case 2: //名次
for(int i=0; i
5.main.c
#include "student.h"
struct Teacher li={102025,"1234","liqianqian"};
stu zhang={202501,"zs","12341",18,1,90,85,88};
stu lis={202502,"ls","12342",18,1,88,91,85};
stu wang={202503,"ww","12343",18,2,88,90,91};
int number_of_student=2;
int main(int argc, const char *argv[])
{
p_stu p_stu_main=creat_stu_list();
p_stu_main[0]=zhang;
p_stu_main[1]=lis;
p_stu_main[2]=wang;
int judgement=judge(p_stu_main);
while(judgement)
{
int choice,flag=0;
printf("----------学生信息管理系统----------\n");
printf("1.录入学生 2.删除学生 3.修改学生信息\n");
printf("4.查找学生 5.学生列表 6.退出管理系统\n");
scanf("%d",&choice);
switch (choice)
{
case 1:type_in_stu(p_stu_main);break;
case 2:delete_stu(p_stu_main);break;
case 3:change_stu(p_stu_main);break;
case 4:check_stu(p_stu_main);break;
case 5:show_stu_list(p_stu_main);break;
case 6:++flag;break;
default:printf("您的输入有误,请重新输入");continue;
}
if(flag)break;
}
free(p_stu_main);
p_stu_main=NULL;
printf("您已退出系统。\n");
return 0;
}
1.登录
2.增删
3.查改
4.列表
这个项目十分有意义,能够综合C语言的知识。