后端网站开发培训,app开发需要哪些知识,七台河新闻在线直播,在线优化网站建设点击蓝字 关注我们不仅仅是图书信息管理系统基于双链表#xff0c;采用面向对象编程方法制作的图书管理系统❞效果演示root用户#xff1a;账号#xff1a;0#xff0c;密码#xff1a;0普通用户#xff1a;账号#xff1a;1001#xff0c;密码#xff1a;666666图书信… 点击蓝字 关注我们不仅仅是图书信息管理系统基于双链表采用面向对象编程方法制作的图书管理系统❞效果演示root用户账号0密码0普通用户账号1001密码666666图书信息没有完全演示只是个大概微信gif只能300帧以内框架结构数据层双链表管理核心层用户管理、图书管理用户管理用户分三种readonly、write、root(可删除数据)功能Exit(退出), Add(添加), Show(显示), Change(修改), Delete(删除), Search(查找)图书管理权限分级暂未实现(可自行实现)功能EXIT(退出), ADD(添加), SHOW(显示), CHANGE(修改), DELETE(删除), SEARCH(查找)ps:用这个双链表框架可以解决99.9%的各种信息管理系统(增删改查)问题那%0.1就是给自己留的后路毕竟没有什么问题可以100%解决以后再跟我提xxx管理系统我就给你扔过去这对代码自己去实现核心部分双链表的实现双链表typedef struct deroy_node{void* data;struct deroy_node* prev;struct deroy_node* next;}deroy_node_t;typedef deroy_node_t* deroy_node_pt;typedef struct deroy_list{int limit_size; deroy_node_pt head; deroy_node_pt tail;}deroy_list_t;typedef deroy_list_t* deroy_list_pt;为什么链表里面的data是void*呢谭浩强的C语言不是这样教的啊void类型是空类型可以转成任意一种类型你不知道你插入的数据的结构体是什么或者说你要插入多种数据的结构体确定的结构体已经不能够满足需求了需要定义void*类型来指向你要添加进链表的结构体数据我们需要实现一些函数来管理链表注意o,前方高能小白勿看功能函数/*初始化链表*/deroy_list_pt deroy_list_create(void);/*插入节点*/int deroy_list_insert_before(deroy_list_t** list_head, int num, void* new_node_data);/*删除节点*/int deroy_list_delete(deroy_list_t** list_head, int num);/*修改节点*/int deroy_list_modify(deroy_list_t** list_head, int num, void* new_node_data);/*遍历节点*/void deroy_list_cuid(deroy_list_t* list_head, void (*do_function)(void*));/*查询数据 返回 数据的位置*/int deroy_list_search(deroy_list_t** list_head, void* find_data, int(*compare)(void*, void*));/*查询数据 返回 数据的指针*/void* deroy_list_find(deroy_list_t** list_head, void* find_data, int(*compare)(void*, void*))为什么我要先把功能函数的原型给列举出来因为你仔细看参数双链表功能实现多次用到回调函数什么是回调函数呢回调函数就是一个通过函数指针调用的函数。❞怎么说呢如果你把函数的指针(地址)作为参数传递给另一个函数当这个指针被用来调用其所指向的函数时我们就说这是回调函数。回调函数能够干什么你学过C知道多肽吧就是一个方法实现多个功能回调函数就是C里面实现多肽的方式举个栗子功能函数里面有个遍历所有节点的功能函数/*遍历节点*/void deroy_list_cuid(deroy_list_t* list_head, void (*do_function)(void*)){int i 0;if (list_head NULL || list_head-limit_size 0) { errno EINVAL;exit(errno); }for (i 0; i list_head-limit_size; i) { (*do_function)(__deroy_list_visit(list_head, i)); }}前面那个判断没啥可看的直接看 (*do_function)(__deroy_list_visit(list_head, i));__deroy_list_visit是个内联函数它的功能就是返回list_head里面的第i个节点数据(void *data)然后将数据给传入的do_function,让dofunction去处理data数据核心层用户管理区实现dofunction/*回调函数 打印所以学生信息*/static void proxy_find_stu(deroy_data_pt pdata){/*遍历学生信息*/if (pdata-type STU) {printf( %d\t%d\t%s\t%d\t%d\n, pdata-type, pdata-id, pdata-name, pdata-sex, pdata-rank); }}/*回调函数 root用户打印所有信息*/static void proxy_find_all(deroy_data_pt pdata){/*遍历所有信息*/printf( %d\t%d\t%s\t%d\t%d\t%d:\t%s\n, pdata-type, pdata-id, pdata-name, pdata-sex, pdata-rank, pdata-acount,pdata-password);} 通过对dofunction的实现我们一个deroy_list_cuid函数可以遍历所有data的id段还是不管什么数据都打印这样就实现了root用户查看的权限更大 如果觉得这个直接两个函数实现不是更好吗如果你想到这里证明你还在思考对两个函数实现更方便但是那是核心层(自己写回调函数)去重新解释这个功能达到了分层的概念或许这里的回调函数应用的不明显这里还有个明显的/*查询数据 返回 数据的位置*/int deroy_list_search(deroy_list_t** list_head, void* find_data, int(*compare)(void*, void*)){int counter 1; deroy_node_pt current NULL;if (list_head NULL || *list_head NULL) { errno EINVAL;exit(errno); }if ((*list_head)-limit_size 0) {return -1; //无数据可查询 } current (*list_head)-head;/*通过传入的comper函数进行比较*/while (compare(current-data, find_data) 0 current-next ! NULL) { current current-next; counter; }if (current-next NULL compare(current-data, find_data) 0)return 0;return counter;}这里的的回调函数要求判断两个数据返回真假/*回调函数 比较db_data_pt数据段的id是否相同*/static int proxy_compare_id(deroy_data_pt pdata, deroy_data_pt other){if (pdata-id other-id)return 1;return 0;}通过核心层的用户管理去实现按id查找还是其他查找方式这里你总不能两个函数解决吧必须要分层不能扯太远咱说的是链表继续..双链表的实现我之前发过一篇循环双链表有图解还算详细循环双链表这个双链表还算可以没有内存泄漏(如果有请告诉我反正我也不会去改)各种判断安全系数高功能完善能处理各种增删改查功能的系统设计核心层用户管理啊~当时想着用双链表实现学生信息管理系统来着码着码着就想把图书信息管理系统也码下来比较学生信息管理系统已经烂大街了我上个学生信息管理系统在知乎都有2000赞了#define STU 0#define TEACHER 1typedef enum Menu{ Exit, Add, Show, Change, Delete, Search}MENU;typedef enum Sex{ MAN, WOMAN}SEX;/*权限*/enum RANK{ READ_ONLY /*只读*/ , WRITE /*读写*/ , ROOT /*root可删除*/};/*学号、专业、姓名、年龄、性别属性。*/typedef struct deroy_data{char type; /*类型*/char rank; /*级别*/int id; /*编号*/char name[10]; /*姓名*/char sex; /*性别*/int acount; /*账号*/char password[20]; /*密码*/void* data; /*其他*/int(*Init)(struct deroy_data* pdata);}deroy_data_t;typedef deroy_data_t* deroy_data_pt;没什么特殊的甚至用户信息少的可怜有点用处的就是权限了然后看到deroy_data里面的void* data段了吗没错我就是想告诉你们这个是扩展功能可扩展用户的其他信息这个我就不实现了比较代码多了你们看着挺烦的然后这个结构体里面的函数指针就相当于C里面的方法可以指向一个功能函数然后就和之前的学生信息管理系统差不多了~/*学生信息管理系统*/int system_proxy_stu(deroy_list_pt ptlist,int user_rank){ rank user_rank;while (1) {switch (menu_proxy_stu()) //菜单选择 {case Exit: //退出程序 system(cls);printf(退出程序\n); Quit();return 1;break;case Show: //显示所有学生信息 system(cls);if (rank READ_ONLY) {printf( 类型\t学号\t姓名\t性别\t权限\n\n); deroy_list_cuid(ptlist, proxy_find_stu); }else if(rank ROOT) {printf( 类型\t学号\t姓名\t性别\t权限\t账号\t密码\n\n); deroy_list_cuid(ptlist, proxy_find_all); } Quit();break;case Add: //添加学生信息 init_proxy_stu(ptlist); Quit();break;case Change: //修改学生信息 proxy_stu_modify(ptlist); Quit();break;case Delete: //删除学生信息 proxy_stu_delete(ptlist); Quit();break;case Search: //查询学生信息 proxy_stu_find(ptlist); Quit();break; } system(cls); }}把所有功能函数都实现了并且功能函数都有权限设置普通用户只能查看普通用户的信息核心层图书管理这个图书管理实现的比用户管理还简单我都没去设置权限问题可自行设计typedef enum BookMenu{ EXIT, ADD, SHOW, CHANGE, DELETE, SEARCH}BOOKMENU;/*图书编号、书名、图书分类、数量、出版日期、登记日期*/typedef struct deroy_book{int iID; /*序号*/char cId[4]; /*编号*/char cName[20]; /*书名*/char cSubject[20]; /*图书分类*/int iNums; /*数量*/char cPublish_data[20];/*出版日期*/char cData[20]; /*登记日期*/int(*Init)(struct deroy_book* pdata); /*初始化函数*/}deroy_book_t;typedef deroy_book_t* deroy_book_pt;简简单单的把基本的图书信息给列举出来只需要实现功能函数即可/*初始化图书数据*/static void init_book_proxy_node(deroy_book_pt self)/*注册图书*/static void register_book_proxy_method(deroy_list_pt ptlist, void* pdata)/*初始化图书信息*/static void init_proxy_book(deroy_list_pt ptlist)/*菜单选择*/static int menu_proxy_book()/*修改图书信息*/static void proxy_book_modify(deroy_list_pt ptlist)/*删除图书信息*/static void proxy_book_delete(deroy_list_pt ptlist)/*查找图书信息*/static void proxy_book_find(deroy_list_pt ptlist)/*图书信息管理系统*/int system_proxy_book(deroy_list_pt ptlist)这些个功能函数都挺简单的都是围绕着之前设计的链表来实现的详情可以看原码这其实就是我将用户管理的代码复制过来改void *data所指向的结构体deroy_book几乎是一模一样的所以说这是个模板是个框架框架定死了你围绕着这个框架去实现功能就行这里提个有趣的就是图书注册日期这里不用管理员去实现直接sprintf(self-cData, %s, __DATE__);__DATE__是一个宏打印的是当前日期打印的是年月日例如Jul 11 2020这个宏我在C语言预处理那里提过可惜看的人不多预处理用户登录首先主函数里面把两个核心层给创建咯 deroy_list_pt pStu_Head deroy_list_create(); //创建用户 deroy_list_pt pBook_Head deroy_list_create(); //创建书籍在创建用户的时候会创建两个用户对象一个root、一个普通read_only,用于初始登录登录就是去调用函数接收函数的返回值 int user_rank load(pStu_Head);if (user_rank 0) {printf(登录失败);return 0; }这个返回值是用户的权限用来层级之间交互int load(deroy_list_pt phead){char account[20],password[20]; //账号密码printf(input acount:);scanf(%s, account);printf(password:);scanf(%s, password);deroy_data_t temp; temp.id atoi(account); deroy_data_pt find_data deroy_list_find(phead, temp, proxy_compare_load);if (find_data 0) {if (strcmp(password, find_data-password) 0) {return find_data-rank; } }return -1;}之而立直接调用链表提供的方法deroy_list_find,自己实现回调函数int proxy_compare_load(deroy_data_pt pdata, deroy_data_pt other){if (pdata-id other-id)return 1;return 0;}为什么是找id而不是用户名呢这里我懒了一下直接将id赋值给account整数方便图个开心「公众号【编程学习基地】后台发送关键字「图书信息管理系统」获取源代码」关键字【图书管理系统】End作者梦凡梦想在终不凡~你们的在看就是对我最大的肯定点个在看好吗~编程学习基地常回基地看看