通讯录
需求分析
-
创建联系人-insert
-
删除联系人-delete
-
搜索联系人-search
-
输出所有联系人-traversal
-
保存文件-save-存储方式key:value的实现
-
加载文件-load-将键值对读入并加入到存储结构中
架构分析
实现分析
底层实现
采用链表实现,因此要定义通讯录结构体,并定义链表的基础操作insert、remove。这里可以直接使用宏定义函数实现。
接口层实现
接口层要实现的函数接口是-add-delete-search-traversal
业务逻辑层
业务层实现的封装是-insert-delete-print-search-save-load
解包和压包
这里将接口层和支持层结合在了一起,解包包括读和写
复盘问题
-
如何进行
struct person
中的业务和数据结构分离?struct person {
char name[MAXNAME]; // 业务
char phone[MAXPHONENUMBER]; // 业务
struct person* pre; // 数据结构
struct person* next; // 数据结构
};思路:将业务剥离出去重新成为一个结构体。
struct person{ // 业务结构
char name[MAXNAMELENGTH];
char phone[MAXPHONENUMBER];
};
struct node{ // 数据结构
struct person* person;
struct node* pre;
struct node* next;
}; -
linux如何解决scanf溢出问题?
-
通过
%n
限制读入长度 -
使用更安全的函数
fgets
代替,注意要fgets
前使用getchar()
清空缓冲区, -
通过
fllush(fp)
刷新缓冲区,使其写入到文件
-
-
为什么要使用二级指针? 解决链表初始空结点因传参无法修改而无法创建头节点的问题。
-
memcpy
和stcpy
的异同点memcpy
用于复制内存块,可以用于任意类型,需要指定n
,数量太大会发生溢出,需要手动处理终止字符串,更加底层,一定条件下速度更快;strcpy
用于复制字符串,终止于空字符串,只适用于字符串,是不安全的,必须保证目标缓冲区能够容纳源字符串 -
fflush(fp)
会自动刷新与fp
相连的缓冲区 -
segment fault
错误如何产生的?数组越界,或者访问空指针指向的内容,案例如下:
fgets
如果获取为空,就会引发segment fault
,因为返回了空指针。