前言:好多电子科技类大学的好多专业在大一或是大二实习的时候,会要求学生做类似于:图书馆管理系统,宿舍管理系统,学生管理系统和公司管理系统等等的系统。
其实,这些系统究其本质都是要求最少做一个能够对信息进行:增,删,改,查的操作的系统,那么,我就用这篇博客来编写一个宿舍管理系统来介绍链表的使用方法吧。
在这里,我要先介绍一下链表的概念:
链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。
那么,用图像表示为:
这里的h为头节点,其他节点的左部分为数据域,右部分为指针域,最后一个节点的指针域指向NULL
第一步,我们要思考将来要录入什么信息,而对于宿舍管理系统,则至少需要录入的信息是:
学生姓名,学生所住的楼号,层数,房间号
那么,我们就来定义一个结构体包含这几项信息:
typedef struct POINT {
char name[20]; //这里定义长度是20,是因为一个汉字占用两个char类型的空间,所以,假设姓名在10 位以内
int num;
int ceng;
int fang;
struct POINT *next; //这里的指针域,必须赋值,而且最后一个节点,要赋值为NULL
}POINT;
第二步,因为在处理信息时,可能会出现处理失败的结果,所以,我们创建一个类型去识别是否成功(即,编写“lhc.h”):
(注意:.h文件中只能存放:函数声明,宏和用户自定义类型)
#ifndef _LHC_H_ //防止多次定义造成错误
#define _LHC_H_
typedef unsigned char boolean //模仿JAVA中的boolean ,定义一个新的数据类型
#define TRUE 1
#define FALSE 0
#define KEEP_ON 1
#define EXIT 0
typedef struct POINT {
int num;
int ceng;
int fang;
char name[20];
struct POINT *next;
}POINT;
boolean defend();
void menu();
void initList(POINT *linkOne);
boolean enteringPoints(POINT *head);
void insertPoint(POINT *head);
POINT *searchPreNode(POINT head, POINT one);
boolean removePoint(POINT *head);
boolean alterPoint(POINT *head);
void showOnePoint(POINT point);
void showPointList(POINT head);
void destoryPointLink(POINT *head);
void sortByRow(POINT head);
int function(POINT *linkOne);
#endif
第三步,开始编写功能函数:
1.因为要对信息进行处理的前提是有信息能够进行操作,所以,编写录入信息函数:
boolean enteringPoints(POINT *head) { //返回值为boolean 类型,是因为这里的参数是 存储 我们要录入信息的链表的首地址
int pnum;
int pceng;
int pfang;
char pname[20]; //前面这四个变量的定义,是为了将来用户输入以及给链表数据域赋值用的
POINT *p; //这个变量的功能是存储一个要变动变量未变动之前的数据的地址
POINT *tail;
if(NULL == head || head->next != NULL) {
return FALSE;
}
printf("请输入楼号,层数,房间,姓名:");
scanf("%d%d%d", &pnum, &pceng, &pfang);
gets(pname);
while(pnum && pceng && pfang) {
p=(POINT *)calloc(sizeof(POINT), 1);
p->num=pnum;
p->ceng=pceng;
p->fang=pfang;
strcpy(p->name, pname);
if(NULL == head->next) {
head->next=p;
} else {
tail->next=p;
}
tail=p;
printf("请输入楼号,层数,房间,姓名:");
scanf("%d%d%d", &pnum, &pceng, &pfang);
gets(pname);
}
return TRUE;
}
2.编写增添数据的函数(即插入数据函数):
在这里,因为增添数据可能是左插入,也可能是右插入,那么,在这里,我就用最常用的左插入来编写插入数据函数:
void insertPoint(POINT *head) {
int newNum;
int newCeng;
int newFang;
char newName[20]; //前面这四个变量,是为用户输入新居民信息用的
int oldNum;
int oldCeng;
int oldFang;
char oldName[20]; //这四个变量,是旧居民(即新居民后面的居民)的信息
POINT *p;
POINT old;
POINT *pre;
printf("请输入新用户信息:");
scanf("%d%d%d", &newNum, &newCeng, &newFang);
gets(newName);
p = (POINT *) calloc(sizeof(POINT), 1);
p->num = newNum;
p->ceng = newCeng;
p->fang = newFang、;
p->next = NULL;
printf("请输入指定用户信息(楼号,层数,房间号、姓名)(实现左插入;若指定点不存在,则,实现尾随追加):");
scanf("%d%d%d", &oldNum, &oldCeng, &oldFang);
gets(oldName);
old.num = oldNum;
old.ceng = oldCeng;
old.fang = oldFang;
pre = searchPreNode(head, old);
if (NULL == pre) { //判断是否为空链表
pre = head;
}
p->next = pre->next;
pre->next = p;
}
以下是该函数原理的示意图:
3.增删改查函数差不多都会用到查找函数,那么,我们就来编写查找函数:
POINT *searchPreNode(const POINT *head, POINT one) {
POINT *p;
POINT *q = NULL;
for (p = head->next; p && (p->num != one.num || p->ceng != one.ceng || p->fang != one.fang); p = p->next) {
q = p;
}
return q; //q为要查找的节点的前驱结点的首地址
}
4.有增添就要想到删除,所以,编写删除函数:
boolean removePoint(POINT *head) { //因为用户可能输入错误信息,导致删除操作失败,所以,返回值为boolean 类型
int num;
int ceng;
int fang;
char name[20];
POINT *pre;
POINT point;
POINT *p;
printf("请输入要删除的用户信息(按照楼号,层数,房间号):");
scanf("%d%d%d", &num, &ceng, &fang);
gets(name);
point.num = num;
point.ceng = ceng;
point.fang =fang;
strcpy(point.name,name);
pre = searchPreNode(head, point);
if (NULL == pre) {
pre = head;
} else if (NULL == pre->next) { //若不是链表内的值,则无需进行删除,直接返回即可
return FALSE;
}
p = pre->next;
pre->next = p->next;
free(p);
return TRUE;
}
5.编写修改用户信息的函数:
boolean alterPoint(POINT *head) { //因为用户可能输入错误信息,导致删除操作失败,所以,返回值为boolean 类型
int oldnum;
int oldceng;
int oldfang;
char oldname[20];
int newnum;
int newceng;
int newfang;
char newname[20];
POINT newPoint;
POINT target;
POINT *pre;
if(!head) {
return FALSE;
}
printf("请输入要修改的用户的信息:");
scanf("%d%d%d", &oldnum, &oldceng, &oldfang);
gets(oldname);
target.num=oldnum;
target.ceng=oldceng;
target.fang=oldfang;
strcpy(target.name, oldname);
pre = searchPreNode(head, target);
if(!pre || NULL !=pre->next ) {
printf("请输入新的用户信息:");
scanf("%d%d%d", &newnum, &newceng, &newfang);
gets(newname);
pre->next->num=newnum;
pre->next->ceng=newceng;
pre->next->fang=newfang;
strcpy(pre->next->name, newname);
return TRUE;
}
return FALSE;
}
6.编写显示函数:
因为一个一个显示都要进行一个重复的步骤,就是显示一个居民的信息,
那么,就先编写显示一个居民的信息的函数:
void showOnePoint(const POINT *point) {
printf(" %-d %-d %-d %s \n",point.num,point.ceng,point.fang,point.name);
}
在此基础上,再来编写显示全部居民信息的函数:
void showPointList(const POINT *head) {
POINT *p;
printf("\n ---------------------------------------------");
printf("\n 楼号 层数 房间号 户主姓名\n");
for (p = head->next; p; p = p->next) {
showOnePoint(p);
}
printf(" ---------------------------------------------");
printf("\n");
}
7.因为用户可能会有销毁当前信息表的需求,所以这一步编写销毁当前信息表的函数:
void destoryPointLink(POINT *head) {
POINT *p;
while (head && head->next) {
p = head->next;
head->next = p->next;
free(p);
}
head->next = NULL;
}
8.可能用户会有将信息排序的需求,所以,这里来编写排序函数:
void sortByRow(POINT *head) {
POINT *pre;
POINT *next;
POINT *nextTemp;
POINT temp;
for (pre = head->next; pre; pre = pre->next) { //我们在这里用的是冒泡排序法
for (next = pre->next; next; next = next->next) {
if ((pre->num >= next->num) && (pre->ceng >= next->ceng) && (pre->fang >= next->fang)) {
temp = *pre; //这里是按照楼号->层数->房间号顺序,从大到小排序的
*pre = *next;
*next = temp;
nextTemp = pre->next;
pre->next = next->next;
next->next = nextTemp;
}
}
}
}
第三步,谋划主函数:
为了在没有多少技术的基础上显示自己的逼格,这里就可以编写一个简易的安全锁函数:
boolean defend() {
int ok= 0;
char code[20];
int count=0;
printf(" 安全监测系统\n");
printf(" 请输入8位密码(初始密码为12345678;两次错误输入后,程序结束):\n");
while(!ok && count < 2) {
gets(code);
ok=(0 == strcmp(code,"12345678"));
if (!ok) {
printf("\n密码错误,");
++count;
} else {
ok = 1;
}
if(!ok&&count<2) {
printf("请再次输入: ");
}
}
if (ok) {
printf("\n\1小区管理系统欢迎您\1\n");
return TRUE;
} else {
printf("很遗憾,程序结束\n");
return FALSE;
}
}
因为之前做了很多功能函数,在主函数中就可以让用户选择要使用的功能函数,完成对于信息的处理,而且,在完成信息的处理操作后,还需要询问用户是否结束运行,如果否,则继续执行之后的指令。
而有了这个想法,我们不妨编写一个菜单函数:
void menu() {
printf("\n 小区户主信息管理系统\n ");
printf(" ****************************************************************************************************************\n");
printf(" |--------------------------------------------------------------------------------------------------------------|\n");
printf(" | 1 2 3 4 5 6 7 |\n");
printf(" |--------------------------------------------------------------------------------------------------------------|\n");
printf(" | 终止程序 用户信息插入 用户信息排序 用户信息显示 用户信息删除 用户信息表销毁 用户信息修改 |\n");
printf(" |--------------------------------------------------------------------------------------------------------------|\n");
printf(" ****************************************************************************************************************\n");
printf("请输入指令:(输入其他数字表示结束程序)\n");
}
一切就绪,那么,我们现在来编写主函数吧:
int main() {
POINT linkOne = {0};
boolean safe;
int flag = 1;
printf("制作人: xx专业 xxx\n");
safe = defend();
if(safe == FALSE) {
return 0;
}
initList(&linkOne);
while(flag) {
flag = function(&linkOne);
}
return 0;
}
那么,现在来总结一下 manageSystem.c 的内容:
#include <stdio.h>
#include <malloc.h>
#include <string.h>
#include "lhc.h"
int function(POINT *linkOne) {
int order;
int ok;
scanf("%d",&order);
switch(order) {
case 1:
insertPoint(linkOne);
showPointList(*linkOne);
break;
case 2:
sortByRow(*linkOne);
showPointList(*linkOne);
break;
case 3:
showPointList(*linkOne);
break;
case 4:
if(TRUE == removePoint(linkOne)) {
printf("删除结果如下:\n");
showPointList(*linkOne);
} else {
printf("删除失败!\n");
}
break;
case 5:
alterPoint(linkOne);
printf("修改结果如下:\n");
showPointList(*linkOne);
break;
case 6:
destoryPointLink(linkOne);
printf("用户信息表已被销毁!!!\n");
printf("输入1:重新录入信息\n输入其他:终止程序!\n");
scanf("%d", &ok);
if(1 != ok) {
printf("即将终止程序...\n");
return EXIT;
}
initList(linkOne);
break;
default :
destoryPointLink(linkOne);
return EXIT;
}
printf("\n输入任意继续程序...\n");
getchar();
getchar();
menu();
return KEEP_ON;
}
void insertPoint(POINT *head) {
int newNum;
int newCeng;
int newFang;
char newName[20];
int oldNum;
int oldCeng;
int oldFang;
char oldName[20];
POINT *p;
POINT old;
POINT *pre;
printf("请输入新用户信息:");
scanf("%d%d%d", &newNum, &newCeng, &newFang);
gets(newName);
p = (POINT *) calloc(sizeof(POINT), 1);
strcpy(p->name, newName);
p->num = newNum;
p->ceng = newCeng;
p->fang = newFang;
p->next = NULL;
printf("请输入指定用户信息:楼号、层数、房间号(实现左插入;若指定用户不存在,则,实现尾随追加):");
scanf("%d%d%d", &oldNum, &oldCeng, &oldFang);
old.num = oldNum;
old.ceng = oldCeng;
old.fang = oldFang;
pre = searchPreNode(*head, old);
if (NULL == pre) {
pre = head;
}
p->next = pre->next;
pre->next = p;
}
POINT *searchPreNode(POINT head, POINT one) {
POINT *p;
POINT *q = NULL;
for (p = head.next; p && (p->num != one.num || p->ceng != one.ceng || p->fang != one.fang); p = p->next) {
q = p;
}
return q;
}
boolean removePoint(POINT *head) {
int num;
int ceng;
int fang;
char name[20];
POINT *pre;
POINT point;
POINT *p;
printf("请输入要删除的用户信息(按照楼号,层数,房间号):");
scanf("%d%d%d", &num, &ceng, &fang);
gets(name);
point.num = num;
point.ceng = ceng;
point.fang =fang;
strcpy(point.name,name);
pre = searchPreNode(*head, point);
if (NULL == pre) {
pre = head;
} else if (NULL == pre->next) {
return FALSE;
}
p = pre->next;
pre->next = p->next;
free(p);
return TRUE;
}
boolean alterPoint(POINT *head) {
int oldnum;
int oldceng;
int oldfang;
char oldname[20];
int newnum;
int newceng;
int newfang;
char newname[20];
POINT newPoint;
POINT target;
POINT *pre;
if(!head) {
return FALSE;
}
printf("请输入要修改的用户的信息(按照楼号,层数,房间号,用户名):");
scanf("%d%d%d", &oldnum, &oldceng, &oldfang);
gets(oldname);
target.num=oldnum;
target.ceng=oldceng;
target.fang=oldfang;
strcpy(target.name, oldname);
pre = searchPreNode(*head, target);
if(!pre || NULL !=pre->next ) {
printf("请输入新的用户信息(按照楼号,层数,房间号,用户名):");
scanf("%d%d%d", &newnum, &newceng, &newfang);
gets(newname);
pre->next->num=newnum;
pre->next->ceng=newceng;
pre->next->fang=newfang;
strcpy(pre->next->name, newname);
return TRUE;
}
return FALSE;
}
void showOnePoint(POINT point) {
printf(" %-d %-d %-d %s \n",point.num,point.ceng,point.fang,point.name);
}
void showPointList(POINT head) {
POINT *p;
printf("\n ---------------------------------------------");
printf("\n 楼号 层数 房间号 户主姓名\n");
for (p = head.next; p; p = p->next) {
showOnePoint(*p);
}
printf(" ---------------------------------------------");
printf("\n");
}
void destoryPointLink(POINT *head) {
POINT *p;
while (head && head->next) {
p = head->next;
head->next = p->next;
free(p);
}
head->next = NULL;
}
void sortByRow(POINT head) {
POINT *pre;
POINT *next;
POINT *nextTemp;
POINT temp;
for (pre = head.next; pre; pre = pre->next) {
for (next = pre->next; next; next = next->next) {
if ((pre->num >= next->num) && (pre->ceng >= next->ceng) && (pre->fang >= next->fang)) {
temp = *pre;
*pre = *next;
*next = temp;
nextTemp = pre->next;
pre->next = next->next;
next->next = nextTemp;
}
}
}
}
boolean enteringPoints(POINT *head) {
int pnum;
int pceng;
int pfang;
char pname[20]; //前面这四个变量的定义,是为了将来用户输入以及给链表数据域赋值用的
POINT *p; //这个变量的功能是存储一个要变动变量未变动之前的数据的地址
POINT *tail;
if(NULL == head || head->next != NULL) {
return FALSE;
}
printf("请输入楼号,层数,房间,姓名:");
scanf("%d%d%d", &pnum, &pceng, &pfang);
gets(pname);
while(pnum && pceng && pfang) {
p=(POINT *)calloc(sizeof(POINT), 1);
p->num=pnum;
p->ceng=pceng;
p->fang=pfang;
strcpy(p->name, pname);
if(NULL == head->next) {
head->next=p;
} else {
tail->next=p;
}
tail=p;
printf("请输入楼号,层数,房间,姓名:");
scanf("%d%d%d", &pnum, &pceng, &pfang);
gets(pname);
}
return TRUE;
}
void initList(POINT *linkOne) {
enteringPoints(linkOne);
printf("\n当前户主信息表为:\n");
showPointList(*linkOne);
menu();
}
void menu() {
printf("\n 小区户主信息管理系统\n ");
printf(" ***********************************************************************************************\n");
printf(" |---------------------------------------------------------------------------------------------|\n");
printf(" | 1 2 3 4 5 6 |\n");
printf(" |---------------------------------------------------------------------------------------------|\n");
printf(" | 用户信息插入 用户信息排序 用户信息显示 用户信息删除 用户信息修改 用户信息表销毁 |\n");
printf(" |---------------------------------------------------------------------------------------------|\n");
printf(" ***********************************************************************************************\n");
printf("请输入指令:(输入其他数字表示结束程序)\n");
}
boolean defend() {
int ok= 0;
char code[20];
int count=0;
printf(" 安全监测系统\n");
printf(" 请输入8位密码(初始密码为12345678;两次错误输入后,程序结束):");
while(!ok && count < 2) {
gets(code);
ok=(0 == strcmp(code,"12345678"));
if (!ok) {
printf("\n密码错误,");
++count;
} else {
ok = 1;
}
if(!ok&&count<2) {
printf("请再次输入(最后一次机会啦!): ");
}
}
if (ok) {
printf("\n\1小区管理系统欢迎您\n");
return TRUE;
} else {
printf("很遗憾,程序结束\n");
return FALSE;
}
}
int main() {
POINT linkOne = {0};
boolean safe;
int flag = 1;
printf("制作人: xx专业 xxx\n");
safe = defend();
if(safe == FALSE) {
return 0;
}
initList(&linkOne);
while(flag) {
flag = function(&linkOne);
}
return 0;
}
配合前面编写过的 “lhc.h”就可以完成啦。
上面的版本需要多文件联编,不会用命令行编译的同学可能就用不了这个方法,所以,在下方,在本博主改进下,在一个.c文件中直接编译也能运行了:
#include <stdio.h>
#include <malloc.h>
#include <string.h>
typedef unsigned char boolean;
#define TRUE 1
#define FALSE 0
#define KEEP_ON 1
#define EXIT 0
typedef struct POINT {
int num;
int ceng;
int fang;
char name[20];
struct POINT *next;
}POINT;
boolean defend();
void menu();
void initList(POINT *linkOne);
boolean enteringPoints(POINT *head);
void insertPoint(POINT *head);
POINT *searchPreNode(POINT head, POINT one);
boolean removePoint(POINT *head);
boolean alterPoint(POINT *head);
void showOnePoint(POINT point);
void showPointList(POINT head);
void destoryPointLink(POINT *head);
void sortByRow(POINT head);
int function(POINT *linkOne);
int function(POINT *linkOne) {
int order;
int ok;
scanf("%d",&order);
switch(order) {
case 1:
insertPoint(linkOne);
showPointList(*linkOne);
break;
case 2:
sortByRow(*linkOne);
showPointList(*linkOne);
break;
case 3:
showPointList(*linkOne);
break;
case 4:
if(TRUE == removePoint(linkOne)) {
printf("删除结果如下:\n");
showPointList(*linkOne);
} else {
printf("删除失败!\n");
}
break;
case 5:
alterPoint(linkOne);
printf("修改结果如下:\n");
showPointList(*linkOne);
break;
case 6:
destoryPointLink(linkOne);
printf("用户信息表已被销毁!!!\n");
printf("输入1:重新录入信息\n输入其他:终止程序!\n");
scanf("%d", &ok);
if(1 != ok) {
printf("即将终止程序...\n");
return EXIT;
}
initList(linkOne);
break;
default :
destoryPointLink(linkOne);
return EXIT;
}
printf("\n输入任意继续程序...\n");
getchar();
getchar();
menu();
return KEEP_ON;
}
void insertPoint(POINT *head) {
int newNum;
int newCeng;
int newFang;
char newName[20];
int oldNum;
int oldCeng;
int oldFang;
char oldName[20];
POINT *p;
POINT old;
POINT *pre;
printf("请输入新用户信息:");
scanf("%d%d%d", &newNum, &newCeng, &newFang);
gets(newName);
p = (POINT *) calloc(sizeof(POINT), 1);
strcpy(p->name, newName);
p->num = newNum;
p->ceng = newCeng;
p->fang = newFang;
p->next = NULL;
printf("请输入指定用户信息:楼号、层数、房间号(实现左插入;若指定用户不存在,则,实现尾随追加):");
scanf("%d%d%d", &oldNum, &oldCeng, &oldFang);
old.num = oldNum;
old.ceng = oldCeng;
old.fang = oldFang;
pre = searchPreNode(*head, old);
if (NULL == pre) {
pre = head;
}
p->next = pre->next;
pre->next = p;
}
POINT *searchPreNode(POINT head, POINT one) {
POINT *p;
POINT *q = NULL;
for (p = head.next; p && (p->num != one.num || p->ceng != one.ceng || p->fang != one.fang); p = p->next) {
q = p;
}
return q;
}
boolean removePoint(POINT *head) {
int num;
int ceng;
int fang;
char name[20];
POINT *pre;
POINT point;
POINT *p;
printf("请输入要删除的用户信息(按照楼号,层数,房间号):");
scanf("%d%d%d", &num, &ceng, &fang);
gets(name);
point.num = num;
point.ceng = ceng;
point.fang =fang;
strcpy(point.name,name);
pre = searchPreNode(*head, point);
if (NULL == pre) {
pre = head;
} else if (NULL == pre->next) {
return FALSE;
}
p = pre->next;
pre->next = p->next;
free(p);
return TRUE;
}
boolean alterPoint(POINT *head) {
int oldnum;
int oldceng;
int oldfang;
char oldname[20];
int newnum;
int newceng;
int newfang;
char newname[20];
POINT newPoint;
POINT target;
POINT *pre;
if(!head) {
return FALSE;
}
printf("请输入要修改的用户的信息(按照楼号,层数,房间号,用户名):");
scanf("%d%d%d", &oldnum, &oldceng, &oldfang);
gets(oldname);
target.num=oldnum;
target.ceng=oldceng;
target.fang=oldfang;
strcpy(target.name, oldname);
pre = searchPreNode(*head, target);
if(!pre || NULL !=pre->next ) {
printf("请输入新的用户信息(按照楼号,层数,房间号,用户名):");
scanf("%d%d%d", &newnum, &newceng, &newfang);
gets(newname);
pre->next->num=newnum;
pre->next->ceng=newceng;
pre->next->fang=newfang;
strcpy(pre->next->name, newname);
return TRUE;
}
return FALSE;
}
void showOnePoint(POINT point) {
printf(" %-d %-d %-d %s \n",point.num,point.ceng,point.fang,point.name);
}
void showPointList(POINT head) {
POINT *p;
printf("\n ---------------------------------------------");
printf("\n 楼号 层数 房间号 户主姓名\n");
for (p = head.next; p; p = p->next) {
showOnePoint(*p);
}
printf(" ---------------------------------------------");
printf("\n");
}
void destoryPointLink(POINT *head) {
POINT *p;
while (head && head->next) {
p = head->next;
head->next = p->next;
free(p);
}
head->next = NULL;
}
void sortByRow(POINT head) {
POINT *pre;
POINT *next;
POINT *nextTemp;
POINT temp;
for (pre = head.next; pre; pre = pre->next) {
for (next = pre->next; next; next = next->next) {
if ((pre->num >= next->num) && (pre->ceng >= next->ceng) && (pre->fang >= next->fang)) {
temp = *pre;
*pre = *next;
*next = temp;
nextTemp = pre->next;
pre->next = next->next;
next->next = nextTemp;
}
}
}
}
boolean enteringPoints(POINT *head) {
int pnum;
int pceng;
int pfang;
char pname[20]; //前面这四个变量的定义,是为了将来用户输入以及给链表数据域赋值用的
POINT *p; //这个变量的功能是存储一个要变动变量未变动之前的数据的地址
POINT *tail;
if(NULL == head || head->next != NULL) {
return FALSE;
}
printf("请输入楼号,层数,房间,姓名:");
scanf("%d%d%d", &pnum, &pceng, &pfang);
gets(pname);
while(pnum && pceng && pfang) {
p=(POINT *)calloc(sizeof(POINT), 1);
p->num=pnum;
p->ceng=pceng;
p->fang=pfang;
strcpy(p->name, pname);
if(NULL == head->next) {
head->next=p;
} else {
tail->next=p;
}
tail=p;
printf("请输入楼号,层数,房间,姓名:");
scanf("%d%d%d", &pnum, &pceng, &pfang);
gets(pname);
}
return TRUE;
}
void initList(POINT *linkOne) {
enteringPoints(linkOne);
printf("\n当前户主信息表为:\n");
showPointList(*linkOne);
menu();
}
void menu() {
printf("\n 小区户主信息管理系统\n ");
printf(" ***********************************************************************************************\n");
printf(" |---------------------------------------------------------------------------------------------|\n");
printf(" | 1 2 3 4 5 6 |\n");
printf(" |---------------------------------------------------------------------------------------------|\n");
printf(" | 用户信息插入 用户信息排序 用户信息显示 用户信息删除 用户信息修改 用户信息表销毁 |\n");
printf(" |---------------------------------------------------------------------------------------------|\n");
printf(" ***********************************************************************************************\n");
printf("请输入指令:(输入其他数字表示结束程序)\n");
}
boolean defend() {
int ok= 0;
char code[20];
int count=0;
printf(" 安全监测系统\n");
printf(" 请输入8位密码(初始密码为12345678;两次错误输入后,程序结束):");
while(!ok && count < 2) {
gets(code);
ok=(0 == strcmp(code,"12345678"));
if (!ok) {
printf("\n密码错误,");
++count;
} else {
ok = 1;
}
if(!ok&&count<2) {
printf("请再次输入(最后一次机会啦!): ");
}
}
if (ok) {
printf("\n\1小区管理系统欢迎您\n");
return TRUE;
} else {
printf("很遗憾,程序结束\n");
return FALSE;
}
}
int main() {
POINT linkOne = {0};
boolean safe;
int flag = 1;
printf("制作人: xx专业 xxx\n");
safe = defend();
if(safe == FALSE) {
return 0;
}
initList(&linkOne);
while(flag) {
flag = function(&linkOne);
}
return 0;
}
这样,运行后结果大致如下图:
本人就在博文中展示三张图来验证下代码的正确性。
底下这张图片的菜单显示有些乱,本人亲自测试,不同的编译器中,会有不同的显示,有的编译器可能能显示正常形态,若实在不行,就需要观众们自己动手,删点空格,这样就能够更加美观地显示了。
有的同学能发现,其实本人编写的代码和好多搜到的代码的功能函数的参数不一样(如果一样的话,请看解释),这里来做一些解释:
有的版本是传递节点的内容,而不是节点的首地址,但是本人对于这种做法十分不屑,因为我们调用函数时,参数占用的是堆栈空间,这个空间不是很大,而且,若是我们编写的函数是递归函数,那么,很容易造成“栈满溢出”现象,虽然这是个小细节,但是,能学到这里的同学,想必也是将C学到了末尾,或者说已经开始了《数据结构与算法》或者另一种语言的学习,所以,我们要多多关注这些小细节,但是,有时候,用指针也会使得我们的代码出现错误,或者“可读性”变差,所以,我们的编程之路还是很漫长的。
这篇博客写于本人大一下,并且在大一暑假进行了改进,大一下时参加过学校实习,所以了解到大概就是这么个操作,至于文件处理,本人学术浅薄,打算将于今后学懂再写博客,希望这篇博客能对于有需求或是接触链表的朋友们有所帮助。
如有意见,欢迎提出,谢谢!!!