先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7
深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新大数据全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
如果你需要这些资料,可以添加V获取:vip204888 (备注大数据)
正文
对存放学生信息的结构体进行改造↓
改造后↓
typedef struct studentmanagement
{
int sz; //记录当前有效的学生信息个数
int capcity; //记录存放学生信息的最大容量
studata stu[]; //柔性数组 用于不确定数组元素个数 实现动态增长
}stumgt;
增加了一个 capcity 表示存放学生信息的最大容量,将stu[100]固定的100个大小改为了柔性数组的形式stu[]放在的最后
设计初始的容量大小和每次增容的大小↓
#define SZ 6 //每次增加的容量个数
#define CAPCITY 3 //一开始设置的容量
用#define宏定义 设定 SZ为6 表示每次增容的个数 CAPCITY为3 表示初始时容量的大小
用宏定义 在后续想更改初始化容量或者增容大小可以直接更改对应宏后面的常量数可维护性更高
3.开辟动态内存空间和初始化
开辟静态空间的方式(直接在栈区申请固定空间)↓
stumgt stus;
改造后开辟动态内存方式↓
stumgt \*stus=(stumgt \*)calloc(1,sizeof(stumgt)+sizeof(studata)\*CAPCITY);//在堆区创建stumgt类型大小的空间给柔性数组分配的空间
在堆区申请空间用到calloc动态内存开辟函数,表示开辟1个 sizeof(stumgt)+sizeof(studata)*CAPCITY)大小的空间,并且将空间都初始化为0…
根据柔性数组的使用 sizeof(stumgt) 表示的是非柔性数组以外的空间大小 sizeof(studata)*CAPCITY)表示柔性数组内部的大小,即CAPCITY个学生信息容量大小
改造后结构传参时直接传指针变量stus即可
初始化学生信息管理结构体变量改造前↓
void initstus(stumgt\* pstus)//初始化学生管理系统这个结果体变量
{
assert(pstus != NULL);
memset(pstus, 0, sizeof(stumgt));
}
初始化学生信息管理结构体变量改造后↓
void initstus(stumgt\* pstus)//初始化学生管理系统这个结构体变量
{
assert(pstus != NULL);
pstus->capcity = CAPCITY; //将最大容量设置为初始化容量大小
}
改造后 只需学生信息管理结构体中的最大容量成员变量初始化为 设置的初始化容量大小
4.设计动态增容自定义函数
在初始化的容量满后需要扩容,此时封装一个扩容函数实现对动态内存增容
函数定义↓
addcapcity(&pstus);
函数定义↓
static void addcapcity(stumgt\*\* pstus)
{
stumgt\* tmp=(stumgt\*)realloc(\*pstus, sizeof(stumgt) + sizeof(studata) \* ((\*pstus)->capcity + SZ)); //在堆区创建stumgt类型大小的空间给柔性数组分配的空间
if (tmp == NULL) // 增容失败 显示错误并返回
{
perror("realloc");
return;
}
else
{
\*pstus = tmp; // 将重新开辟的空间地址赋给main函数里的pstus指针变量
(\* pstus)->capcity += SZ; //最大容量增容 SZ 个
}
}
注意:动态增容函数的实参传参需要是二级指针,因为 realloc重置动态空间函数使用时可能在堆区另外一块区域重新开辟空间返回重新开辟的空间指针,而需要将该指针传stus指针变量里则需要二级指针才能实现,否则只能对形参临时开辟的局部变量赋值…
如果增容失败会返回空指针 经过判断后显示增容失败信息然后返回
增容操作每次增加当前最大容量加SZ个大小后将最大容量增加SZ个供下次继续增容
5.改造增加学生信息自定义函数
有了增容函数后,增加学生信息就不再仅限于最后不能超过固定的学生个数了
改造添加学生信息函数前↓
void addstu(stumgt\* pstus)
{
assert(pstus != NULL);
if (pstus->sz == 100)
{
printf("学生信息已满,无法新增学生信息\n");
return;
}
else
{
system("cls"); //输入学生信息前清屏一次
printf("请输入学生学号:");
char tmp[20] = { 0 };
scanf("%s", tmp);
if (is\_repeat(pstus, tmp)) //学生学号为主要属性 应是唯一的且不能为空
{
printf("输入失败!!!已存在学号信息为%s的学生,不同学生信息不允许设置相同学号\n", tmp);
return;
}
strcpy(pstus->stu[pstus->sz].sno, tmp); //不存在重复时将当前信息拷贝作为学生学号信息
printf("请输入学生名字:");
scanf("%s", pstus->stu[pstus->sz].name);
printf("请输入学生性别:");
scanf("%s", pstus->stu[pstus->sz].sex);
printf("请输入学生年龄:");
scanf("%d", &pstus->stu[pstus->sz].age); //注意年龄这里要&其他的都是地址
printf("请输入学生寝室号:");
scanf("%s", pstus->stu[pstus->sz].roomnum);
printf("请输入学生电话号码:");
scanf("%s", pstus->stu[pstus->sz].number);
printf("请输入学生家庭住址:");
scanf("%s", pstus->stu[pstus->sz].add);
pstus->sz++;
system("cls");
printf("添加成功\n");
}
}
改造添加学生信息函数后↓
void addstu(stumgt\* pstus)
{
assert(pstus != NULL);
if (pstus->sz ==pstus-> capcity) // 当sz有效个数等于最大容量时进入分支
{
addcapcity(&pstus); // 调用增容函数
printf("存储空间已满..增容中...\n"); // 制造增容效果
Sleep(3000); //睡眠3秒
}
if (pstus->sz == pstus->capcity) // 当调用增容后 有效个数还是等于最大容量时则表示增容失败了 此时进入该分支 否则则增容成功 进行后续添加学生信息操作
{
printf("容量已满,无法再添加学生信息\n");
return;
}
else
{
system("cls"); //输入学生信息前清屏一次
printf("请输入学生学号:");
char tmp[20] = { 0 };
scanf("%s", tmp);
if (is\_repeat(pstus, tmp)) //学生学号为主要属性 应是唯一的且不能为空
{
printf("输入失败!!!已存在学号信息为%s的学生,不同学生信息不允许设置相同学号\n", tmp);
return;
}
strcpy(pstus->stu[pstus->sz].sno, tmp); //不存在重复时将当前信息拷贝作为学生学号信息
printf("请输入学生名字:");
scanf("%s", pstus->stu[pstus->sz].name);
printf("请输入学生性别:");
scanf("%s", pstus->stu[pstus->sz].sex);
printf("请输入学生年龄:");
scanf("%d", &pstus->stu[pstus->sz].age); //注意年龄这里要&其他的都是地址
printf("请输入学生寝室号:");
scanf("%s", pstus->stu[pstus->sz].roomnum);
printf("请输入学生电话号码:");
scanf("%s", pstus->stu[pstus->sz].number);
printf("请输入学生家庭住址:");
scanf("%s", pstus->stu[pstus->sz].add);
pstus->sz++;
system("cls");
printf("添加成功\n");
}
}
经过改造后,学生信息容量不局限于是100个而是可以动态增容…
6.改造排序学生信息自定义函数
排序学生信息函数改造前↓
void sortstu(stumgt\* pstus) // 升序排序所有学生记录的函数
{
if (pstus->sz == 0) //判断排序时是否为空
{
printf("当前学生记录为空,无法排序\n");
return;
}
qsort(pstus, pstus->sz, sizeof(studata), cmp_sno);
printf("已按学号完成升序排序\n");
}
排序学生信息函数改造后↓
void sortstu(stumgt\* pstus) // 升序排序所有学生记录的函数
{
if (pstus->sz == 0) //判断排序时是否为空
{
printf("当前学生记录为空,无法排序\n");
return;
}
qsort(pstus->stu, pstus->sz, sizeof(studata), cmp_sno); //
printf("已按学号完成升序排序\n");
}
静态版本学生信息管理结构体成员变量位置不同,排序是对学生信息数组进行排序,所以要将第一个元素改为指向学生数组.
四.学生信息管理系统(动态内存版)源码展示
1.test.c源文件
#define \_CRT\_SECURE\_NO\_WARNINGS
#pragma warning(disable : 6031)
#include"stu.h"
int main()
{
stumgt \*stus=(stumgt \*)calloc(1,sizeof(stumgt)+sizeof(studata)\*CAPCITY);//在堆区创建stumgt类型大小的空间给柔性数组分配的空间
int i = 0;
initstus(stus);
do
{
menu();
printf("请选择:");
scanf("%d", &i);
switch (i)
{
case ADD:
addstu(&stus); // 因为要动态增容变量里的值可能要改变 此时取当前main里的stus变量地址传参过去
break;
case DROP:
dropstu(stus);
break;
case FIND:
search(stus);
break;
case MODIFY:
modifystu(stus);
break;
case TOTAL:
countstu(stus);
break;
case PRINT:
pritstus(stus);
break;
case SORT:
sortstu(stus);
break;
case EXIT:
printf("已退出学生信息管理系统\n");
break;
default:
printf("选择错误,请重新输入\n");
break;
}
} while (i);
return 0;
}
2.stu.h头文件
#pragma once
#include<stdio.h>
#include<string.h>
#include<assert.h>
#include<stdlib.h>
#include<windows.h>
#define SZ 6 //每次增加的容量个数
#define CAPCITY 3 //一开始设置的容量
typedef struct studentdata
{
char sno[20]; //学号
char name[20]; //名字
char sex[5]; //性别
int age; //年龄
char roomnum[20];// 寝室号
char number[12];// 电话号码
char add[20]; //地址
}studata;
typedef struct studentmanagement
{
int sz; //记录当前有效的学生信息个数
int capcity; //记录存放学生信息的最大容量
studata stu[]; //柔性数组 用于不确定数组元素个数 实现动态增长
}stumgt;
enum option //声明 枚举类型 option 对应的枚举常量为实现 管理系统 菜单功能的选项名称 枚举常量不能同名
{
EXIT, //退出
ADD, //添加
DROP, //删除
FIND, //查找
MODIFY, //修改
TOTAL, //统计
PRINT, //打印
SORT, //排序
};
enum option1 // 修改菜单的选择项
{
END, //结束修改
MODALL, //修改整条信息
MODONE //修改某一项信息
};
enum option2 //修改单项的菜单选择项
{
RETURN, //返回上一层
MODSNO, //修改学号
MODNAME, //修改姓名
MODSEX, //修改性别
MODAGE, //修改年龄
MODROOM, //修改寝室号
MODNUMBER, //修改电话号码
MODADDRESS //修改地址
};
enum option3 //统计学生个数菜单 选择项
{
ENDCOUNT, //结束统计
COUNTALL, //统计所有学生信息
COUNTAGE, // 按年龄统计
COUNTROOM, //统计寝室号
COUNTSEX //按性别统计
};
void menu();
//void initstus(stumgt\* pstus);
void addstu(stumgt\*\* pstus);
void pritstus(stumgt\* pstus);
void dropstu(stumgt\* pstus);
void search(stumgt\* pstus);
void modifystu(stumgt\* pstus);
void countstu(stumgt\* pstus);
void sortstu(stumgt\* pstus);
3.stu.c源文件
#define \_CRT\_SECURE\_NO\_WARNINGS
#pragma warning(disable : 6031) //忽略返回值
#include"stu.h"
void menu()
{
printf(" 欢迎使用学生信息管理系统 \n");
printf("\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\n");
printf("# 1.添加新的学生信息 2.删除指定学生信息 #\n");
printf("# 3.查找指定学生信息 4.修改指定学生信息 #\n");
printf("# 5.分类统计学生个数 6.显示所有学生信息 #\n");
printf("# 7.排序所有学生信息 0.退出学生管理系统 #\n");
printf("\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\n");
}
static void modifymenu1()
{
printf("\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\n");
printf("# 1.修改整条学生信息 2.修改某项学生信息 #\n");
printf("# 0.退出修改菜单 #\n");
printf("\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\n");
}
static void modifymenu2()
{
printf("\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\n");
printf("# 1.修改学生学号 2.修改学生姓名 #\n");
printf("# 3.修改学生性别 4.修改学生年龄 #\n");
printf("# 5,修改学生寝室号 6.修改学生电话号码 #\n");
printf("# 7.修改学生家庭住址 0.返回上一步修改 #\n");
printf("\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\n");
}
static void countmenu()
{
printf("\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\n");
printf("# 1.统计所有学生个数 2.按年龄统计学生个数 #\n");
printf("# 3.按寝室号统计学生个数4.按性别统计学生个数 #\n");
printf("# 0.结束统计 #\n");
printf("\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\n");
}
void initstus(stumgt\* pstus)//初始化学生管理系统这个结果体变量
{
assert(pstus != NULL);
pstus->capcity = CAPCITY; // //将最大容量设置为初始化容量大小
}
static void addcapcity(stumgt\*\* pstus)
{
stumgt\* tmp=(stumgt\*)realloc(\*pstus, sizeof(stumgt) + sizeof(studata) \* ((\*pstus)->capcity + SZ)); //在堆区创建stumgt类型大小的空间给柔性数组分配的空间
if (tmp == NULL) // 增容失败 显示错误并返回
{
perror("realloc");
return;
}
else
{
\*pstus = tmp; //
(\* pstus)->capcity += SZ; //最大容量增容 SZ 个
}
}
static int is\_repeat(stumgt\* pstus, char tmp[]) //判断学号信息是否重复
{
int i = 0;
for (i = 0; i < pstus->sz; i++)
{
if (strcmp(tmp, pstus->stu[i].sno) == 0)
{
return 1;
}
}
return 0;
}
void addstu(stumgt\*\* pstus)
{
assert(\*pstus != NULL);
if (( \* pstus)->sz == (\*pstus)->capcity) // 当sz有效个数等于最大容量时进入分支
{
addcapcity(pstus); // 调用增容函数
printf("存储空间已满..增容中...\n"); // 制造增容效果
Sleep(3000); //睡眠3秒
}
if ((\*pstus)->sz == (\*pstus)->capcity) // 当调用增容后 有效个数还是等于最大容量时则表示增容失败了 此时进入该分支 否则则增容成功 进行后续添加学生信息操作
{
printf("容量已满,无法再添加学生信息\n");
return;
}
else
{
system("cls"); //输入学生信息前清屏一次
printf("请输入学生学号:");
char tmp[20] = { 0 };
scanf("%s", tmp);
if (is\_repeat(\*pstus, tmp)) //学生学号为主要属性 应是唯一的且不能为空
{
printf("输入失败!!!已存在学号信息为%s的学生,不同学生信息不允许设置相同学号\n", tmp);
return;
}
strcpy((\*pstus)->stu[(\*pstus)->sz].sno, tmp); //不存在重复时将当前信息拷贝作为学生学号信息
printf("请输入学生名字:");
scanf("%s", (\*pstus)->stu[(\*pstus)->sz].name);
printf("请输入学生性别:");
scanf("%s", (\*pstus)->stu[(\*pstus)->sz].sex);
printf("请输入学生年龄:");
scanf("%d", &(\*pstus)->stu[(\*pstus)->sz].age); //注意年龄这里要&其他的都是地址
printf("请输入学生寝室号:");
scanf("%s", (\*pstus)->stu[(\*pstus)->sz].roomnum);
printf("请输入学生电话号码:");
scanf("%s", (\*pstus)->stu[(\*pstus)->sz].number);
printf("请输入学生家庭住址:");
scanf("%s", (\*pstus)->stu[(\*pstus)->sz].add);
(\*pstus)->sz++;
system("cls");
printf("添加成功\n");
}
}
void pritstus(stumgt\* pstus) //打印所有信息
{
assert(pstus != NULL);
system("cls"); //输出所有信息前先清屏一次
printf("%-10s\t%-10s\t%-5s\t%-10s\t%-10s\t%-12s\t%-20s\t\n", "学号", "姓名", "性别", "年龄", "寝室号", "电话号码", "家庭住址");//先设置好对应字段格式
int i = 0;
for (i = 0; i < pstus->sz; i++)
{
printf("%-10s\t%-10s\t%-5s\t%-10d\t%-10s\t%-12s\t%-20s\t\n", //按设置好的格式对其打印数据
pstus->stu[i].sno,
pstus->stu[i].name,
pstus->stu[i].sex,
pstus->stu[i].age,
pstus->stu[i].roomnum,
pstus->stu[i].number,
pstus->stu[i].add);
}
}
static int findstu(stumgt\* pstus, char tmp[]) //封装的内部 查找学生学号信息的函数 找到返回对应的数组元素下标 没找到返回-1
{
assert(pstus != NULL);
int i = 0;
for (i = 0; i < pstus->sz; i++)
{
if (strcmp(tmp, pstus->stu[i].sno) == 0)
return i;
}
return -1;
}
void dropstu(stumgt\* pstus) //删除学生信息
{
assert(pstus != NULL);
if (pstus->sz == 0) //判断学生记录是否为空
{
printf("当前没有学生信息,无法删除\n");
return;
}
char tmp[20] = { 0 };
printf("输入要删除的学生的学号信息:");
scanf("%s", tmp);
int num = findstu(pstus, tmp); //使用内部封装的查找函数
if (num == -1)
{
printf("没有找到要删除的学生信息\n");
return;
}
else
{
int i = 0;
for (i = num + 1; i < pstus->sz; i++)
{
pstus->stu[i - 1] = pstus->stu[i];
}
pstus->sz--;
printf("已删除学号为%s的学生成员\n", tmp);
}
}
void search(stumgt\* pstus) //查找学生信息的函数 以名字作为查找标准
{
assert(pstus != NULL);
char tmp[20] = { 0 };
printf("请输入要查找的学生姓名:");
scanf("%s", tmp);
system("cls");
printf("已查询到以下姓名为%s的学生信息↓↓↓\n", tmp); //找到后按设置的对齐格式输出查找的信息
printf("%-10s\t%-10s\t%-5s\t%-10s\t%-10s\t%-12s\t%-20s\t\n", "学号", "姓名", "性别", "年龄", "寝室号", "电话号码", "家庭住址");
int i = 0;
**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**
**需要这份系统化的资料的朋友,可以添加V获取:vip204888 (备注大数据)**

**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**
{
int i = 0;
for (i = num + 1; i < pstus->sz; i++)
{
pstus->stu[i - 1] = pstus->stu[i];
}
pstus->sz--;
printf("已删除学号为%s的学生成员\n", tmp);
}
}
void search(stumgt\* pstus) //查找学生信息的函数 以名字作为查找标准
{
assert(pstus != NULL);
char tmp[20] = { 0 };
printf("请输入要查找的学生姓名:");
scanf("%s", tmp);
system("cls");
printf("已查询到以下姓名为%s的学生信息↓↓↓\n", tmp); //找到后按设置的对齐格式输出查找的信息
printf("%-10s\t%-10s\t%-5s\t%-10s\t%-10s\t%-12s\t%-20s\t\n", "学号", "姓名", "性别", "年龄", "寝室号", "电话号码", "家庭住址");
int i = 0;
**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**
**需要这份系统化的资料的朋友,可以添加V获取:vip204888 (备注大数据)**
[外链图片转存中...(img-wQVmj825-1713435596384)]
**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**