C语言 学生管理表(动态数组)

第二次考核任务安排

7618ad7d057f9f5382ee9dc9b9e91128.jpeg

动态数组(单独)

代码块

#define _CRT_SECURE_NO_WARNINGS
#include <stdlib.h>
#include <stdio.h>

int main()
{
	int len;//用于数组长度的计算
	char* arr;//动态数组
	scanf("%d", &len);
	arr = (char*)malloc(sizeof(char*) * len);//分配内存
	
	for (int i = len - 1; i >= 0; i--)//输入值
	{
		arr[i] = i;
		
	}
	for (int i = len - 1; i >= 0; i--)//输出值
	{
		printf ("arr[%d]=%d\n",i,arr[i]);
	}

	printf("sizeof(arr)=%d", sizeof(arr));//性质测试

	return 0;
}

快速排序(单独)

算法讲解

视频讲解更加生动便于理解
https://www.bilibili.com/video/BV1at411T75o/?spm_id_from=333.337.search-card.all.click&vd_source=3ca547207338045ac672be8086fa0cda

代码块

#include <stdio.h>
#include <stdlib.h>
 
#define  N  10
 
//快速排序法
int quick_sort(int *a, int low, int high)
{
	int i = low;	//第一位
	int j = high;	//最后一位
	int key = a[i]; //将第一个数作为基准值-- 先找到一个基准值
 
	//进行排序---> 最终结果就是 左面的 都比基准值小 ,右面的都比 基准值大,所以这是所有循环的结束条件
	while (i < j)
	{
		//下面的循环执行的条件是 如果右面的比基准值大,就赋一下值,否则继续向前移动
                //---如果直接把循环写成下面这样---
		//while(a[j] >= key) //如果下面的不写这个i<j,这个就出错、越界,并且排序不准--理由:
		//如果i<j,并且: 右面的值 大于 基准值 时,j往前移动一个
					//i 跟 j 的可能情况 只有 i<j i==j
		while(i < j && a[j] >= key)//i<j 是 当前while循环的结束条件,如果没有这个,i会大于j,出现越界,错误 
		{
			j--;//继续走
		}//如果不成立,也就是 a[j] <= key;右面的比key小了,那就换个位置
		//把a[j]的数据给a[i]	
		a[i] = a[j];	
 
		//将事先保存好的基准值与左边的值进行比较,如果基准值大,保持不变,i往前
		//然后 判断一下这个新的a[i],也就是之前的a[j]跟key值的关系---> 一定是 a[i]<key
		//所以把i向前移动一下,i++
		while(i < j && a[i] <= key)
		{
			i++;
		}
		//移动完以后,把新的位置的a[i]的数值 给刚才的 a[j],然后开始下一次循环
		a[j] = a[i];
	}
 
	//跳出循环,将基准值放入数据a[i]中
	a[i] = key;
	//对基准值左边 的所有数据 再次进行快速查找(递归)
	if (i-1 > low) 
	{
		quick_sort(a, low, i-1);
	}
 
	//对基准值右边的所有数据再次进行快速查找(递归)
	if (i+1 < high)
	{
		quick_sort(a, i+1, high);
	}
 
	return 0;
} 
 
int main(int argc, const char *argv[])
{
	int a[N] = {1, 3, 5, 7, 9, 2, 4, 6, 8, 0};//先整了个数组,初始化了一堆数	
 
	int i = 0;
	printf("排序前:\n");
	for(i = 0; i < N; i++)
	{
		printf("%d ", a[i]);
	}
	putchar(10);
 
	//调用-快排
	quick_sort(a, 0, N-1);//数组,0 ,9
														
	printf("排序后:\n");
	for(i = 0; i < N; i++)
	{
		printf("%d ", a[i]);
	}
	putchar(10);
	
	return 0;
}
————————————————
版权声明:本文为CSDN博主「细雨青峦」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qz652219228/article/details/120070756

最终代码块

头文件(声明函数)

#pragma once
#ifndef __STU_H_
#define __STU_H_
/*
自定义一个结构体数据类型
名字是Student简写成Stu
*/
typedef struct Student
{
	char name[20];//姓名 例:谢时佑
	char stu_num[11];//学号 例:2300090532
	short grade;//班级 例:2305
	short  age;//年龄 例:18
	short chinese;//语文成绩 例:90
	short maths;//数学成绩 例:120
	short english;//英语成绩 例:40
	int score;//总得分

}Stu;

void Mune();

void Array_printf(Stu* Arr, int len);

int Array_add(Stu* Arr, int len, int add_len);

void Array_inquire(Stu* Arr,int len);

int Array_delete(Stu* Arr, int len);

void Array_modification(Stu* Arr, int len);

int quick_sort(Stu* arr, int old_left, int old_right);

int Stu_upload(Stu* Arr,int len);

void Stu_Save(Stu* Arr, int len);


#endif // !1

源文件(定义函数)

我注释打这么多,花了好多时间,好好看

#define _CRT_SECURE_NO_WARNINGS
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "Stu_function.h"

/*
输入参数:无
返回值:无
函数介绍:负责打印菜单
*/
void Mune()
{

	printf("┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓\n");
	printf("┃──────────────────请选择功能────────────────────────┃\n");
	printf("┃─── 1.查询──────────────────────────────────────────┃\n");
	printf("┃─── 2.添加──────────────────────────────────────────┃\n");
	printf("┃─── 3.删除──────────────────────────────────────────┃\n");
	printf("┃─── 4.修改──────────────────────────────────────────┃\n");
	printf("┃─── 5.排序并保存────────────────────────────────────┃\n");
	printf("┃────────────────────────────────────────────────────┃\n");
	printf("┃────────────────────────────────────────────────────┃\n");
	printf("┃────────────────────────────────────────────────────┃\n");
	printf("┃────────────────────────────────────────────────────┃\n");
	printf("┃─── 0.不保存退出────────────────────────────────────┃\n");
	printf("┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛\n");

}
/*
输入参数: “Arr”数组  “len”原来数组长度
返回值:无
函数介绍:打印数组全部内容
*/
void Array_printf(Stu* Arr, int len)
{

	printf(" ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓\n");
	for (int i = 0; i < len; i++)
	{
		Arr[i].score = (Arr[i].chinese + Arr[i].maths + Arr[i].english);//计算总分
		printf(" ┃ 姓名:%s\t┃ 学号:%s\t┃ 班级:%hd\t┃ 年龄:%hd\t┃ 语文成绩:%hd\t┃ 数学成绩:%hd\t┃ 英语成绩:%hd\t┃ 总分成绩:%d\t┃\n", Arr[i].name, Arr[i].stu_num, Arr[i].grade, Arr[i].age, Arr[i].chinese, Arr[i].maths, Arr[i].english, Arr[i].score);
	}
	printf(" ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛\n");
	
}

/*
输入参数: “Arr”数组  “len”原来数组长度  “add_len”增加数组长度
返回值:"len"新的数组长度
函数介绍:添加列表
*/
int Array_add(Stu* Arr, int len, int add_len)
{
	/*printf("请输入需要增加的数组长度:");
	scanf("%d", &add_len);
	len += add_len;
	Arr = (Stu*)realloc(Arr, len * sizeof(Stu));//mmd放里面输入就空指针了*/
	if (Arr == NULL) return len ;
	for (int i = 1; i <= add_len; i++)
	{
		printf("                请输入姓名:");
		scanf("%s", Arr[len - i].name);
		printf("                请输入学号:");
		scanf("%s", Arr[len - i].stu_num);
		printf("                请输入班级:");
		scanf("%hd", &Arr[len - i].grade);
		printf("                请输入年龄:");
		scanf("%hd", &Arr[len - i].age);
		printf("                请输入语文成绩:");
		scanf("%hd", &Arr[len - i].chinese);
		printf("                请输入数学成绩:");
		scanf("%hd", &Arr[len - i].maths);
		printf("                请输入英语成绩:");
		scanf("%hd", &Arr[len - i].english);
	}
	return len;
}
/*
输入参数: “Arr”数组  “len”原来数组长度  
返回值:无
函数介绍:根据学号来查询全部信息
*/
void Array_inquire(Stu* Arr, int len)
{
	printf("                请输入查询的学号\n");
	char stuNum[11];
	char cmp=0;//用来检测是否检测完
	scanf("%s", stuNum);
	for (int i = 0; i < len; i++)
	{
		if (strcmp(stuNum,Arr[i].stu_num) ==0 )//字符串比较是否相等
		{
			printf("┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓\n");
			printf("┃姓名:%s\t┃ 学号:%s\t┃ 班级:%hd\t┃ 年龄:%hd\t┃ 语文成绩:%hd\t┃ 数学成绩:%hd\t┃ 英语成绩:%hd\t┃\n", Arr[i].name, Arr[i].stu_num, Arr[i].grade, Arr[i].age, Arr[i].chinese, Arr[i].maths, Arr[i].english);
			printf("┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛\n");
			cmp++;
		}
	}
	if (cmp == 0)
	{
		printf("                什么都没查到哦\n");
	}

}
/*
输入参数: “Arr”数组  “len”原来数组长度
返回值:无
函数介绍:根据学号来删除信息
*/
int Array_delete(Stu* Arr, int len)
{
	printf("                请输入删除的学号\n");
	char stuNum[11];//临时数组用来比较
	char cmp = 0;//用来检测是否检测完
	scanf("%s", stuNum);
	for (int i = 0; i < len; i++)
	{
		if (strcmp(stuNum, Arr[i].stu_num) == 0)//字符串比较是否相等
		{
			for (int j = i; j < len; j++)
			{
				Arr[j] = Arr[j + 1];
				
				
			}
			cmp++;
			printf("已经删除\n");
		}
	}
	if (cmp == 0)
	{
		printf("                什么都没查到哦\n");
	}
	return (len - cmp);
}
/*
输入参数: “Arr”数组  “len”原来数组长度
返回值:无
函数介绍:根据学号来修改信息
*/
void Array_modification(Stu* Arr, int len)
{
	printf("                请输入修改的学号\n");
	char stuNum[11];
	char cmp = 0;//用来检测是否检测完
	scanf("%s", stuNum);
	for (int i = 0; i < len; i++)
	{
		if (strcmp(stuNum, Arr[i].stu_num) == 0)//字符串比较是否相等
		{
			printf("                请输入姓名:");
			scanf("%s", Arr[i].name);
			printf("                请输入学号:");
			scanf("%s", Arr[i].stu_num);
			printf("                请输入班级:");
			scanf("%hd", &Arr[i].grade);
			printf("                请输入年龄:");
			scanf("%hd", &Arr[i].age);
			printf("                请输入语文成绩:");
			scanf("%hd", &Arr[i].chinese);
			printf("                请输入数学成绩:");
			scanf("%hd", &Arr[i].maths);
			printf("                请输入英语成绩:");
			scanf("%hd", &Arr[i].english);
			printf("------------添加成功-----------");
			cmp++;
		}
	}
	if (cmp == 0)
	{
		printf("                什么都没查到哦\n");
	}


}


/*
输入参数:"arr"数组   “old_left”排序左点   “old_right”排序右点
返回值:0
函数介绍:快速排序
*/
int quick_sort(Stu* arr, int old_left, int old_right)
{
	
	int new_left = old_left;	//左标点
	int new_right = old_right;	//右标点
	Stu new_arr = arr[new_left]; //将第一个数设为基准值

	if (new_left >= new_right)
	{
		
		return 0;
	}
	while (new_left<new_right)//排序结果为,左小右大递增
	{
		while ((new_left < new_right)&&( new_arr.score<=arr[new_right].score))//如果右标点数大于基准值,即右边不光下标数大而且总分也大
		{

			new_right--;//右标点左移1位

		}//直到出现右值小于基准值
		
		if (new_left < new_right)
		{
			arr[new_left] = arr[new_right];//左值赋右
			new_left++;
		}

		while ((new_left < new_right) && (new_arr.score >= arr[new_left].score))//如果左标点数小于基准值,即左边不光下标数小而且总分也小
		{
			new_left++;//左标点右移1位

		}//直到出现左值大于基准值
		if (new_left < new_right)
		{
			arr[new_right] = arr[new_left];//右值赋左
			new_right--;
		}

		if (new_left >= new_right)
		{
			arr[new_right] = new_arr;//把丢失的最开始左值即基准值赋值给现在的左右值
		}
			

	}


	printf("***************\n");
	


		quick_sort(arr, old_left, new_right-1);//把基准值左边的再排序
	
		quick_sort(arr, new_left+1, old_right);//把基准值右边的再排序

	return -1;
}



/*
输入参数: “Arr”数组  “len”原来数组长度
返回值:无
函数介绍:加载
*/
int Stu_upload(Stu* Arr,int len)
{
	
	FILE* r_fp = fopen("Stu.txt", "r");//打开文件,只读模式
	if (r_fp == NULL) return 0;
	int i = 0;//用于下标定位
	while (fgetc(r_fp) != EOF)//判断文件指针是否到达文件末尾
	{
		fseek(r_fp, -1, SEEK_CUR);//指针在当前位置后退一位,因为判断时进了
		Arr = (Stu*)realloc(Arr, (len +2 + i) * sizeof(Stu));
		int a = fscanf(r_fp, "%s %s %hd %hd %hd %hd %hd ", Arr[i].name, Arr[i].stu_num, &Arr[i].grade, &Arr[i].age, &Arr[i].chinese, &Arr[i].maths, &Arr[i].english);
		i++;
	
	}
	fclose(r_fp);//关闭文件指针
	
	return len+i;
}

/*
输入参数: “Arr”数组  “len”原来数组长度
返回值:无
函数介绍:读取
*/
void Stu_Save(Stu* Arr, int len)
{
	FILE* w_fp = fopen("Stu.txt", "w");//打开文件,只写模式
	if (w_fp == NULL) return ;
	int i = 0;//用于下标定位
	while (len)//判断文件指针是否到达文件末尾
	{
		
		
		int a = fprintf(w_fp, "%s %s %hd %hd %hd %hd %hd ", Arr[i].name, Arr[i].stu_num, Arr[i].grade, Arr[i].age, Arr[i].chinese, Arr[i].maths, Arr[i].english);
		i++;
		len--;

	}
	fclose(w_fp);//关闭文件指针

}

源文件(主函数)

#define _CRT_SECURE_NO_WARNINGS
#include <stdlib.h>
#include <stdio.h>

#include "Stu_function.h"

//---------------------------------

//---------------------------------
int main()
{
	int Len = 0;//初始化数组长度
	Stu* Arr = (Stu*)malloc(20* sizeof(Stu));//初始化动态数组
	if (Arr == NULL) return 0;studentc
	int Add_len=0;
	int menu_selection;//用于菜单选择检测
	int mune_cmp;//用于暂时返回检测
	if (Arr == NULL) return 0;
	
	Len =Stu_upload(Arr,Len);//从文件中加载学生表
	Arr = (Stu*)realloc(Arr, (Len + 1) * sizeof(Stu));

	while (true)
	{
		
		Array_printf(Arr, Len);
		Mune();
		printf("                请选择你的功能:");
		scanf("%d", &menu_selection);
		switch (menu_selection)
		{
		case 0://退出ok
			return 0;
		case 1://查询ok
			Array_inquire(Arr, Len);
			break;
		case 2://添加ok

			printf("                请输入需要增加的数组长度:");
			scanf("%d", &Add_len);
			Len += Add_len;
			Arr = (Stu*)realloc(Arr, Len * sizeof(Stu));
			Len = Array_add(Arr, Len, Add_len);
			break;
		case 3://删除ok
			Len=Array_delete(Arr, Len);
			
			break;
		case 4://修改ok
			Array_modification(Arr, Len);
			break;
		case 5://排序并保存
			quick_sort(Arr, 0, Len-1);
			Stu_Save(Arr,Len);//保存到文件
			break;
		default:
			break;
		}
		printf("       *****输入任意返回******\n");
		scanf("%d",&mune_cmp);
		system("cls");//清理屏幕
	}
	return 0;
}

易错点讲解

对于刚上手的同学,经常会出现以下错误

1.scanf无法使用

一定要在第一行代码宏定义
#define _CRT_SECURE_NO_WARNINGS
数组不需要&,其他都需要&

2.scanf_s函数又不太了解

scanf_s在输入字符串的时候
一定要用
scanf_s("%s",Str,sizeof(Str));的格式

  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值