1 前言
时间是检验真理的唯一标准,只用项目才能锻炼一个人的能力,但是,当一个人在一个圈混久了,你的能力就不会再成长,所以你一定要破圈。
作为一个程序员一定要学会不断的进步。同时要吸收不同代码的优秀思想。
本系统开发暂时不涉及到链表操作,使用的数据结构为结构体数组。
2 相关系统的统计
见附录
3 开发流程
3.1 系统架构的搭建
一个好的系统一定是逻辑清晰的,所以一定要学会绘制流程图,通过流程图来表示自己的思想。
3.2 菜单的打印
菜单函数一般包括2个部分,一个部分是简单的菜单函数的打印,一种是菜单函数的选择,常见的是将菜单函数和菜单选择封装到一起,但是我自己比较喜欢将两个函数分开来写,就是一个只负责界面的显示,也算是前端,一个是负责逻辑的处理,算是后端吧。
关于菜单的循环打印,常见的方式有do while while(1)等等 ,但是我自己喜欢使用的是递归,也就是程序执行完以后,在此调用程序本身。
这里有一个问题,就是输入的数据是整型还是字符型的问题,还有就是当输入的其他值的时候怎么处理。解决方式一,就是严格控制输入,如果输入其他值就输出错误提醒。还有一种解决方式就是可以在输入的时候使用c++的读入方式使用cin进行读取,防止系统死机或者退出。
3.3 结构体的设置
3.4 增加函数编写
常见的添加函数包括,一次只添加一个,这个最简单,另外一种就是可以多条添加,多条添加一种是使用手动控制变量的for循环添加,一种使用字符y控制的while方式的添加。
添加函数高级一点的需要做判重处理,判重处理中常见的int使用双等号即可,字符型的使用strcmp函数进行判断,需要注意的是当重复后需要将数据个数的处理,根据具体的情况进行处理。
3.5 显示函数的编写
显示函数的编写主要目的是显示所有的数据,记得增加表头,方便理解数据的含义,同时记得使用\t来进行缩进,使用-来选择对齐方式,使用.2f来控制浮点类型小数点的个数。使用4d来控制数据宽度。
曾经遇到的问题,字符型的变量,开的数组太小,输入长数据的时候,将字符结尾的\0覆盖掉了,导致数据的粘连。
3.6 保存文件的编写
保存文件直接使用fwrite进行操作处理就行了,需要注意的是直接以结构体的方式进行写入。记得关闭文件。就不要使用fprintf了,具体原因查看读取文件。
3.7 读取文件的编写
为什么要进行读取文件,因为输入数据数据比较麻烦,而且有的时候这些数据是系统自动生成的。
常见的文件读取有两种方式,
一种是使用fscanf进行读取,按照一个数据一个数据的读取,加载到结构体数组中,但是这种操作涉及到一个问题就是我不知道加载了多少条数据,如果涉及到继续添加数据就很被动,不知道数据已经存放到数组中的那个位置,如果是简单的输出数据还好说,因为定义数组的时候一定有一个大小,我直接使用for循环将所有的数据输出即可。但是发现有许多的空数据也被输出了,但是发现有一个特点就是空数据的int类型默认的值是0,所以我在输出数据的时候检测一下int类型的数据是否为0,如果为0我就不输出,这样就可以将所有有用的数据输出。
改进:我也可以编写一个函数,来检测int类型的数据是否为0来判断是否有数据,如果有,我就使用一个变量加加,从而判断出数据的位置,然后直接根据数据的位置直接输出,同时也可以根据位置进行添加了。总之,打印,测试是程序员的基本技能。
弊端:这样读取是按照一个一个数据读取的,如果项目变了,结构体的内容变了,所有的数据都要重新,移植性太差!!!
直到后来遇到它,陪我春秋冬夏,然后我就再也没有使用第一种方式,所以,作为程序员一定要开阔眼界,学习优秀的代码,掌握,拿来主义,比自己写的低端代码要好的多。
第二种使用fread来进行读取,它是可以按照结构体的大小来读取的,一次读取一个结构体,可以使用一个变量来加加,这样就同时解决了数据的个数问题,同时在移植的时候直接将结构体的名字改了即可,方便简单快捷。
解决问题的方式不是唯一的,但是你可以进行尝试,其中对于变量个数的解决方式我遇到过把数据的个数单独在存一个文件,运行的时候从文件中读取,或者在存放数据的时候将数据的位置也一并存在同一个文件中。
3.8 修改函数的编写
修改函数的编写和添加函数的判重是类似的,目的是根据条件遍历所有数据,找到修改的函数,提取出位置,然后整体将数据更新,或者根据提示更新部分数据。
可以做的人行化一点就是在修改之间将原数据打印出来,并且提示是否修改。如果错误,打印出错误提示。
3.9 删除函数的编写
删除的本质就是移动数据,将后一条数据把前一条数据进行覆盖,最后一条数据情况,常见的处理方式有两种,一种是数据迁移,将后一条的数据移动到前一天数据上,同时将最后一条数据清零,或者直接将数据个数减一,不显示最后一条。但是这种方式如果接头体的变量过多,后期更改和移植比较费劲,推荐直接使用数组移动。
3.10 查询函数的编写
查询函数其实只是使用了删除函数中的一部分,根据条件找到数据后直接显示即可,么有技术含量。
3.11 数据处理的编写
最常见的数据处理就是排序,一般使用冒泡法的交换排序即可。简单容易理解。最好在排序后尽量调用一下数据显示的函数,直观的看到现象。
4 知识点的整理
4.1 宏定义
例如:#define N 100 表示其中一种宏定义,为什么要使用宏定义,使用宏定义的作用是将以后可能改动的变量提取出来,方便后期的修改和维护。
4.2 结构体
为什么要使用结构体,使用结构体的目的是将不同的数据类型,但是相关的数据类型整合起来,方便管理。
4.3 全局变量
全局变量的作用是将每个函数都要访问的变量作为全局变量,方便每个函数进行访问,而不用传入参数和返回参数,缺点是可移植性比较差,如果将此函数移植到其他项目,需要将使用到的变量一并移植过去。
4.4 头文件
头文件一般包括的是系统编写好的库函数,也就是别人已经封装好的函数,自己直接调用即可,我们没有必要将已经有的功能重新开发,但是如果水平高了,可以参考它的实现方式。
4.5 函数声明
为啥要进行函数声明,函数声明的作用是告诉编译器可能需要编译的函数,如果你的函数编写是按照调用关系顺序写下来的,是可以不需要的,函数声明的作用就是可以方便读者知道你程序用到了那些函数,起到了什么作用。编写程序就可以不用在意顺序关系,只需要处理程序逻辑,不用管调用方式。
4.6 注释
为啥要写注释,注释的目的是便于读者和自己方便理解程序,写注释是一个优秀的程序员必备的素质,同样的变量、函数的命名,程序编写的格式控制等。