学生管理系统 (梳理)
1.目标明确
A.学生:查询学生个人信息(基本、课程)
B.老师:查询老师个人信息
C.管理员:增删改查
2.数据存储:数据库里(文件)
保存哪些数据:
a.保存所有用户信息的文件users.txt
b.每个文件保存用户具体信息jack.txt merry.txt
3.准备知识
枚举enum
单链表
结点
泛型(void*)
- void*任意指针类型,这个指针变量可以指向任意的数据类型,使用这个变量的时候必须转化为对应的类型
枚举
枚举是一种公共类型,同一片内存空间可能存在多种值
(让多个变量共用一种类型)
宏定义:(没有联系,不能将多个值当做一种类型来看待)
#define teacher 0
#define student 1
#define administrator 2
//默认值从零开始,后边依次递增
enum Type{
teacher;//0
student;//1
administrator;//2
}
enum Type tt = teacher;
数据结构
线性表——数组
优点:查询方便
缺点:增删效率低
单链表
优点:增删效率极高
缺点:查询不方便
- 创建一个链表需要有头指针和尾指针,头指针永远不动指向第一个结点,尾指针用来记录当前的尾结点
结点:存储数据单元(一个结点同时包含数据域和指针域,一般为结构体)
1.数据域:存储具体数据 90
2.指针域:记录下一个结点或上一个结点
链表的使用
/*
从终端输入整数,用链表存储,输出所有数据
数据域:整数
指针域:*
*/
#include <stdio.h>
//定义一个类型,结点类型
typedef struct score{//struct Score是一种类型
int score;//数据域
struct score* next;//指向下一个结点的指针域
}Score;
//typedef是类型重定义将Score代替struct Score(单纯名字的替换)
int main(){
//链表头指针很重要(结点的第一个地址)
//定义一个头指针
//struct Score *pHeader;类型重定义前定义头指针的方法
Score *pHeader = NULL;//Score *pHeader == NULL;类等价于型重定义前定义头指针的方法
//尾指针
Score *pTail = NULL;
int i = 0;
while(i < 3){
//先创建一个结构体来存储数据
Score temp = {};
printf("请输入成绩:");
scanf("%d",&(temp,score));
//判断是否是第一个结点
if(pHeader ==NULL){
//头指针指向第一个结点
pHeader = &temp;
//尾指针指向第一个结点
pTail = &temp;
} else{
//让当前的这个next指向这个结点
pHeader->next = &temp;
//尾指针指向最后一个结点
pTail = &temp;
}
i++;
}
//输出
//临时指针指向头结点
Score *pTemp = pHeader;
while(1){
//输出当前这个结点数据
printf("%d",pTemp->score);
//指针指向下一个结点
if(pTemp->next == NULL){
break;
}else{
pTemp = pTemp->next;
//尾指针
}
}
return 0;
}
由于局部变量的局限性,以及系统分配的地址会被释放导致出现了指向不明的情况,所以应该改进代码为手动分配内存,手动释放,这样就不会出现指向不明的担心。
#include <stdio.h>
#include <stdlib.h>
//定义一个类型,结点类型
typedef struct score{//struct Score是一种类型
int score;//数据域
struct score* next;//指向下一个结点的指针域
}Score;
//typedef是类型重定义将Score代替struct Score(单纯名字的替换)
int main(){
//链表头指针很重要(结点的第一个地址)
//定义一个头指针
//struct Score *pHeader;类型重定义前定义头指针的方法
Score *pHeader = NULL;//类等价于宏定义前定义头指针的方法
//尾指针
Score *pTail = NULL;
int i = 0;
while(i < 3){
//先创建一个结构体来存储数据
Score *pNode = (Score*)malloc(sizeof(Score));//手动分配内存空间
if(pNode == NULL){
exit(EXIT_FAILURE);
}
//初始化指针量
pNode->next = NULL;
printf("请输入成绩:");
scanf("%d",&(pNode->score));
//判断是否是第一个结点
if(pHeader == NULL){
//头指针指向第一个结点
pHeader = pNode;
//尾指针指向第一个结点
pTail = pNode;
} else{
//让当前的这个next指向这个结点
pTail->next = pNode;
//尾指针指向最后一个结点
pTail = pNode;
}
i++;
}
//输出
//临时指针指向头结点
Score *pTemp = pHeader;
while(1){
//输出当前这个结点数据
printf("%d",pTemp->score);
//指针指向下一个结点
if(pTemp->next == NULL){
break;
}else{
pTemp = pTemp->next;
//尾指针
}
}
pTemp = pHeader->next;
while(1){
//释放当前结点
free(pHeader);
//指针指向下一个结点
if(pTemp == NULL){
break;
}else{
pHeader = pTemp;
pTemp = pTemp->next;
}
}
return 0;
}