当前位置: 首页 > news >正文

C语言应用实例:学生管理系统1(指针、结构体综合应用,动态内存分配)

前面我们学习了指针和结构体,接下来我们以 学生管理系统 为例,综合运用一下它们

要求实现功能:增删查改

一、功能实现

1.菜单

为了方便使用,首先我们应当创建一个菜单函数,便于后续操作

void menu() {printf("Student Manage\n");printf("==[1001]添加学生==\n");printf("==[1002]查询所有学生==\n");printf("==[1003]根据ID查询学生==\n");printf("==[1004]根据ID修改信息==\n");printf("==[1005]根据ID删除信息==\n");printf("==[1006]退出系统==\n");printf("请输入功能编号:\n");
}

2.添加

接下来我们可以围绕上述功能分别定义函数来实现

首先是添加学生操作(addStu)

为了减少内存占用同时提高运行效率,这里我们采取动态分配的方式来分配内存

struct Student *addStu(Student *stulist, int *size, int *len) {//扩容判断int s = *size;int l = *len;if (s == l) {l = l * 2;struct Student *newStulist = (Student *)malloc(sizeof(Student) * l);for (int i = 0; i < s; i++) {newStulist[i] = stulist[i];}stulist = newStulist;printf("***扩容完成len=%d***\n", l);}printf("请输入\n姓名 学号 年龄 学分\n");char name[50];int id;int age;float score;scanf("%s %d %d %f", name, &id, &age, &score);//创建一个学生结构体变量Student stu;//把信息都存入学生结构体中strcpy(stu.name, name);stu.id = id;stu.age = age;stu.score = score;stulist[s] = stu;*size = s + 1;*len = l;printf("添加成功\n");return stulist;
}

注:这里需要注意,由于重新分配了内存,并返回了新结构体,所以主函数处应注意接收返回值,否则调用的仍是旧的内存地址,会出现乱码(如下)

 // 修复:接收ctrl函数的返回值struct Student *newStulist = ctrl(stulist, &size, &len);if (newStulist == 0) {  // 退出系统free(stulist);break;}stulist = newStulist;  // 更新指针

3.查找

1)查找所有

传递、调用,代码如下

void printAllStu(Student *stulist, int *size) {int s = *size;printf("======All Students======\n");//分割线for (int i = 0; i < s; i++) {struct Student stu = stulist[i];printf("--姓名:%s | 年龄:%d | 学号:%d | 学分:%.2f|--\n", stu.name, stu.age, stu.id, stu.score);}
}

2)ID查找

同理,代码如下

void getStuById(Student *stulist, int *size) {int s = *size;int id;printf("请输入一个学生ID:\n");scanf("%d", &id);for (int i = 0; i < s; i++) {struct Student stu = stulist[i];if (stu.id == id) {printf("ID存在,信息如下:\n");printf("--姓名:%s | 年龄:%d | 学号:%d | 学分:%.2f|--\n", stu.name, stu.age, stu.id, stu.score);return;}}printf("没有查找到ID为%d的学生!\n", id);
}

4.删除

同上,删除时只需将删除位置后的数往前挪动,覆盖住原数后size-1即可

代码如下

void delStuById(Student *stulist, int *size) {int s = *size;struct Student stu;int id;printf("请输入一个学生ID:\n");scanf("%d", &id);int index = -1;for (int i = 0; i < s; i++) {stu = stulist[i];if (stu.id == id) {index = i;break;}}if (index == -1) {printf("没有查找到ID为%d的学生\n", id);return;}for (int i = index; i < s - 1; i++) {stulist[i] = stulist[i + 1];}printf("ID存在,被删除的信息如下:\n");printf("--姓名:%s | 年龄:%d | 学号:%d | 学分:%.2f|--\n", stu.name, stu.age, stu.id, stu.score);*size = s - 1;printf("没有查找到ID为%d的学生!\n", id);
}

5.更改

循环、判断、修改、传递,代码如下

void changeInfoById(Student *stulist, int *size) {int s = *size;int id;printf("请输入一个学生ID:\n");scanf("%d", &id);for (int i = 0; i < s; i++) {struct Student stu = stulist[i];if (stu.id == id) {printf("ID存在,信息如下:\n");printf("--姓名:%s | 年龄:%d | 学号:%d | 学分:%.2f|--\n", stu.name, stu.age, stu.id, stu.score);printf("请输入新的信息:\n姓名 学号 年龄 学分\n");char name[50];int sid;int age;float score;scanf("%s %d %d %f", name, &sid, &age, &score);strcpy(stu.name, name);stu.id = sid;stu.age = age;stu.score = score;stulist[i] = stu;return;}}printf("没有查找到ID为%d的学生!\n", id);
}

二、完整代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>struct Student {char name[50];int id;int age;float score;
};void menu() {printf("Student Manage\n");printf("==[1001]添加学生==\n");printf("==[1002]查询所有学生==\n");printf("==[1003]根据ID查询学生==\n");printf("==[1004]根据ID修改信息==\n");printf("==[1005]根据ID删除信息==\n");printf("==[1006]退出系统==\n");printf("请输入功能编号:\n");
}
/*
//测试用例
void initTestData(Student *stulist, int *size, int *len){char str[5]={'a','b','c','d','e'};for(int i=0;i<100;i++){char name[50]="Name";name[4]=str[i%5];int id=i+100;int age=18+i%80;float score=12.5+i;scanf("%s %d %d %f", name, &id, &age, &score);//创建一个学生结构体变量Student stu;//把信息都存入学生结构体中strcpy(stu.name, name);stu.id = id;stu.age = age;stu.score = score;stulist[s] = stu;*size=s+1;}}
*/struct Student *addStu(Student *stulist, int *size, int *len) {//扩容判断int s = *size;int l = *len;if (s == l) {l = l * 2;struct Student *newStulist = (Student *)malloc(sizeof(Student) * l);for (int i = 0; i < s; i++) {newStulist[i] = stulist[i];}stulist = newStulist;printf("***扩容完成len=%d***\n", l);}printf("请输入\n姓名 学号 年龄 学分\n");char name[50];int id;int age;float score;scanf("%s %d %d %f", name, &id, &age, &score);//创建一个学生结构体变量Student stu;//把信息都存入学生结构体中strcpy(stu.name, name);stu.id = id;stu.age = age;stu.score = score;stulist[s] = stu;*size = s + 1;*len = l;printf("添加成功\n");return stulist;
}//打印所有学生信息
void printAllStu(Student *stulist, int *size) {int s = *size;printf("======All Students======\n");for (int i = 0; i < s; i++) {struct Student stu = stulist[i];printf("--姓名:%s | 年龄:%d | 学号:%d | 学分:%.2f|--\n", stu.name, stu.age, stu.id, stu.score);}}//根据id查找学生信息
void getStuById(Student *stulist, int *size) {int s = *size;int id;printf("请输入一个学生ID:\n");scanf("%d", &id);for (int i = 0; i < s; i++) {struct Student stu = stulist[i];if (stu.id == id) {printf("ID存在,信息如下:\n");printf("--姓名:%s | 年龄:%d | 学号:%d | 学分:%.2f|--\n", stu.name, stu.age, stu.id, stu.score);return;}}printf("没有查找到ID为%d的学生!\n", id);
}//根据id修改信息
void changeInfoById(Student *stulist, int *size) {int s = *size;int id;printf("请输入一个学生ID:\n");scanf("%d", &id);for (int i = 0; i < s; i++) {struct Student stu = stulist[i];if (stu.id == id) {printf("ID存在,信息如下:\n");printf("--姓名:%s | 年龄:%d | 学号:%d | 学分:%.2f|--\n", stu.name, stu.age, stu.id, stu.score);printf("请输入新的信息:\n姓名 学号 年龄 学分\n");char name[50];int sid;int age;float score;scanf("%s %d %d %f", name, &sid, &age, &score);strcpy(stu.name, name);stu.id = sid;stu.age = age;stu.score = score;stulist[i] = stu;return;}}printf("没有查找到ID为%d的学生!\n", id);
}//根据ID删除学生信息
void delStuById(Student *stulist, int *size) {int s = *size;struct Student stu;int id;printf("请输入一个学生ID:\n");scanf("%d", &id);int index = -1;for (int i = 0; i < s; i++) {stu = stulist[i];if (stu.id == id) {index = i;break;}}if (index == -1) {printf("没有查找到ID为%d的学生\n", id);return;}for (int i = index; i < s - 1; i++) {stulist[i] = stulist[i + 1];}printf("ID存在,被删除的信息如下:\n");printf("--姓名:%s | 年龄:%d | 学号:%d | 学分:%.2f|--\n", stu.name, stu.age, stu.id, stu.score);*size = s - 1;printf("没有查找到ID为%d的学生!\n", id);
}//控制面板
struct Student *ctrl(Student *stulist, int *size, int *len) {int cid = 0;scanf("%d", &cid);if (cid == 1001) {stulist = addStu(stulist, size, len);} else if (cid == 1002) {printAllStu(stulist, size);} else if (cid == 1003) {getStuById(stulist, size);} else if (cid == 1004) {changeInfoById(stulist, size);} else if (cid == 1005) {delStuById(stulist, size);} else if (cid == 1006) {free(stulist);return 0;} else {printf("输入有误,请重试!");}return stulist;
}int main() {int len = 10;int size = 0;struct Student *stulist = (Student *)malloc(sizeof(Student) * len);while (1) {printf("===========begin=========\n");menu();// 修复:接收ctrl函数的返回值struct Student *newStulist = ctrl(stulist, &size, &len);if (newStulist == 0) {  // 退出系统free(stulist);break;}stulist = newStulist;  // 更新指针printf("===========End===========\n\n");}return 0;
}

三、常见问题

1.为什么要传递指针而不是数据本身?

函数内修改的是局部变量而不是原数据本身,如果想要修改原数据还需要在主函数中接收返回值,而传递地址(指针)则可以直接修改原数据,省去部分步骤

2.为什么数组不被定义就可以直接使用?

(以本文中stulist为例)

C语言中,指针可以使用数组下标语法:ptr[i]等价于*(ptr + i)

已知数组本身就是指针数据,即一个地址,所以指针变量在被分配内存后可以当作数组使用

http://www.dtcms.com/a/572931.html

相关文章:

  • 找制作网站公司网页制作教程 赵丰年 pdf
  • ffplay 嵌入
  • TDengine 产品组件 taosX
  • 链表相关的算法题(2)
  • 10月谷歌新政 | 涉及真金游戏、约会社交、个人贷款、医疗健康等类别App
  • python实现语音转文本STT
  • 十大免费建站app做网站公司不给源码
  • 07.docker介绍与常用命令
  • 【Docker下部署高可用】StarRocks 存算一体架构高可用部署要点
  • 小型工厂怎么找外贸客户?
  • 【Android】正式打包发布
  • 寻找做网站的合作伙伴北京北京网址建设
  • PyTorch2 Python深度学习 - 模型保存与加载
  • 南京html5网站建设今天发生的重大新闻5条
  • 台州网站排名优化公司中国石油第一建设公司官网
  • JS原型和原型链
  • Rust 赋能图片批量处理:从 ImageKit 实现到行业前沿优化实践
  • ceph osd down排查
  • Android 14 系统启动流程深度解析:内置SD卡挂载流程
  • 【Qt】大数据量表格刷新优化--只刷新可见区域
  • 基于 React 的倒计时组件实现:暴露方法供父组件状态管理
  • 2.每日机器学习——张量(Tensors)
  • wordpress换php7出错内蒙古seo公司
  • 设计模式——桥接模式(bridge)
  • 阳光家园广州网站个人网站如何做即时支付
  • Arbess零基础学习 - 使用Arbess+GitLab实现.Net 项目构建/主机部署
  • 【数据结构】PriorityQueue优先队列:基于堆(heap)实现
  • PCB设计如何防止别人抄板?
  • macOS自定义安装PlatformIO Core
  • VSCode中Copilot的询问、编辑、代理有啥区别?