✨C语言程序项目✨
代码的成长,就是在一次一次的刻意练习中不断成长。
😊1.猜数字
🐼2.三子棋
🦔3.本地保存的动态人员管理系统
前言
首先,我们要对文件进行区分即定义头文件:member.h、 测试文件:test.c、和具体实现文件:Contact.c
一、❤️初始设置通讯录的个体特征
首先,要明白描述一个人的具体特征中要包括姓名,年龄,性别,电话号码,和具体居住地址。所以我们在C语言中要建立一个具体描述一个人的成员结构体。
#include<stdio.h>
#include<string.h>
#include<assert.h>
#include<stdlib.h>
#include<Windows.h>
enum MAX//使用常量来定义对应数组指标的最大值,便于维护
{
ARR_MAX = 3,//使用enum来定义常量可以避免变量污染即可以定义
NAME_MAX = 10,
SEX_MAX = 5,
ARESS_MAX = 20,
TEL_MAX = 13
};
typedef struct peo//定义成员结构体并重命名使得struct peo等同于peo便于书写使用
{
char name[NAME_MAX];
char sex[SEX_MAX];
int old;
char tel_num[TEL_MAX];
char aress[ARESS_MAX];
}peo;
定义完了成员结构体便需要将成员结构体集合成人员管理系统。首先我们要了解到,一个管理系统要包括几种特征标签:现有人员数量,最大容量,和人员存放:这人员的存放有两种实现方式,一(静态版本)利用数组,来建立即创建系统结构体。
typedef struct SqLinst
{
//因为实现的是静态所以要开辟成员数组
peo arr[ARR_MAX];
int size;
int sum_size;
}SL;
但是,这种静态版本会占用栈上太多空间,影响程序运行.而且刚开始用的时候并不会有那么多人的信息,一上来就有那么多空间.根本用不完导致空间的浪费,让运行受到妨碍.所以我们要使得内存能够随着使用,以及数据的增多,内存也不断地变化.故我们要对管理结构体进行调整.转换思路.
typedef struct SqLinst//重命名系统结构体,便于使用
{
//因为实现的是动态所以要创建指针指向动态开辟空间,后续利用动态开辟来将成员集合到指针指向的空间
peo* arrry;
int size;
int sum_size;
}SL;
二.🤞主体函数的实现
根据系统性质我们要创建系统结构体对象并且对其中内容进行初始化,利用memset进行重置并赋值.所以我们要编写初始化结构函数.
//test.c
#include "list.h"
int main()
{
SL my_new;//创建系统结构体
SqListInit(&my_new);//结构体传参一般只用传入创建的系统结构体的地址
}
//list.h头文件进行相应包含和声明
void SqListInit(SL* new);
//Contact.c
static void ImProve_SumSize(SL* new)//static修饰函数则会将函数函数的外链性
{
peo* ret = (peo*)realloc(new->arrry, (new->sum_size + ARR_MAX)*sizeof(peo));/*利用realloc对数组进行扩容进一
增加一个初始数组最大容量,先存在临 时指针变量中*/
if (ret)
{
new->arrry= ret;//将临时指针赋给系统成员data存放处
new->sum_size += ARR_MAX;//扩容成功后就要将最大容量进行更改
printf("扩容成功\n");
}
else
{
printf("扩容失败\n");
return;
}
}
void judge(SL* new)
{
while (new->size >= new->sum_size)//判断是否满,若现有数据等于最大容量
{
printf("内存已满,即将进行扩容\n");
ImProve_SumSize(new);//扩容函数
}
}
void reset(SL* new)
{
memset(new->arrry, 0, sizeof(peo)*new->size);//利用memset进行内容重置.
new->sum_size = ARR_MAX;//将最大容量设为预先在max枚举常量列举的数组初始最大值
new->size = 0;//将现有容量置为0
}
void SqListInit(SL* new)
{
new->size = 0;
printf("初始化中\n");
int i = 0;
Sleep(1000);
system("cls");
int j = 0;
for (i = 0; i < 20; i++)
{
printf("进度条:");
for (j = 0; j <= i; j++)
{
printf("*");
}
Sleep(1000);
system("cls");
} //实现进度条初始化界面,来体现进入系统的过程
assert(new); //判断系统结构体指针是不是空指针,防止解引用空指针的问题出现
peo* tem = (peo*)malloc(sizeof(peo) * ARR_MAX);//动态开辟成员连续存储内存块,得到人员信息存放地址将动态开辟的地址存 //放到临时指针变量若不为空,才能将tem赋给成员数组的指针
if (tem != NULL)//进行判空
{
new->arrry = tem;
}
else
{
printf("通讯录创建失败\n");
return;
}
reset(new);//封装重置函数,对系统内的内容进行重置
peo ret = {
0 };
FILE* pf = fopen("ContactList.txt", "r");//对保存在本地的通讯录文件进行打开
if (pf == NULL)//判断是否打开文件成功,若不成功则会返回空指针
{
perror("SqListInit");//若出现错误则将错误信息进行打印
return;
}
while (fread(&ret, sizeof(peo), 1, pf))//对文件数据进行二进制读取
{
judge(new);//判断读取过程中的内存情况,若不够进行扩容
new->arrry[new->size] = ret;
new->size++;
}
printf("初始化完成\n");
Sleep(1000);//界面完善
system(