如果有任何想法可以提高我的 API 质量,我将不胜感激。提前致谢。
int ll_create(linked_list_p list, void (*print_data)(uint8_t)) {
if (list == NULL) {
list = calloc(1, sizeof(linked_list_p));
return 0;
}
return -1;
}
int ll_destroy(linked_list_p list) {
if (list == NULL) {
return -1;
}
linked_list_node_p node_ptr = list->tail;
for(int i = list->size-1; i > 0; i--) {
if (node_ptr->next) {
free(node_ptr->next);
node_ptr->next = NULL;
}
node_ptr = node_ptr->previous;
if (node_ptr->next->previous) {
node_ptr->next->previous = NULL;
}
free(node_ptr->next);
node_ptr->next = NULL;
}
free(list->head);
list->head = NULL;
list->size = 0;
return 0;
}
int ll_get(linked_list_p list, uint32_t index, uint8_t *data){
if (list == NULL) {
return -1;
}
if (index >= list->size) {
return -1;
}
linked_list_node_p node_ptr = list->head;
for (int i = 0; i < index; i++){
if (node_ptr == NULL) {
return -1;
}
node_ptr = node_ptr->next;
}
*data = node_ptr->data.data;
return 0;
}
int ll_remove(linked_list_p list, uint32_t index) {
if (list == NULL) {
return -1;
}
if (index > list->size-1) {
return -1;
}
linked_list_node_p node_to_delete;
if (index == 0) {
node_to_delete = list->head;
list->head = list->head->next;
free(list->head->previous);
list->head->previous = NULL;
free(node_to_delete->next);
node_to_delete->next = NULL;
node_to_delete = NULL;
free(node_to_delete);
list->size --;
return 0;
}
if (index == list->size-1) {
node_to_delete = list->tail;
list->tail = list->tail->previous;
free(list->tail->next);
list->tail->next = NULL;
free(node_to_delete->previous);
node_to_delete->previous = NULL;
free(node_to_delete);
node_to_delete = NULL;
list->size --;
return 0;
}
linked_list_node_p node_ptr = list->head;
for (int i = 0; i < index-1; i++) {
node_ptr = node_ptr->next;
}
node_to_delete = node_ptr->next;
node_ptr->next->next->previous = node_ptr;
node_ptr->next = node_ptr->next->next;
node_to_delete->next = NULL;
node_to_delete->previous = NULL;
free(node_to_delete->next);
free(node_to_delete->previous);
list->size--;
return 0;
}
这是主要的:我已经尝试自己测试它但不确定它是否是正确的方法。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "linked_list.h"
static void print_data(uint8_t data){
printf("%d", data);
}
int main(int argc, char *argv[]){
static linked_list_t list;
ll_create(&list, print_data);
ll_add_first(&list, 2);
ll_insert(&list, 13, 0);
ll_remove(&list, 32);
ll_add_last(&list, 3);
ll_add_last(&list, 4);
ll_print(&list);
ll_destroy(&list);
ll_print(&list);
ll_add_last(&list, 5);
ll_add_last(&list, 6);
ll_add_first(&list, 7);
ll_print(&list);
ll_print_backward(&list);
ll_insert(&list, 8, 4);
printf("list size : %ld\n", list.size);
ll_insert(&list, 8, list.size);
ll_print(&list);
//TODO use every API functions
// ll_get
uint8_t get_data = 0;
ll_get(&list, 95, &get_data);
printf("got data : %d\n\n", get_data);
// ll_remove
ll_remove(&list, 5);
ll_print(&list);
// ll_insert
ll_insert(&list, 10, 2);
ll_print(&list);
// ll_contains
uint8_t data_to_find = 96;
printf("The data %d is in the list : %s", data_to_find, ll_contains(&list, data_to_find) ? "true\n" : "false\n");
data_to_find = 10;
printf("The data %d is in the list : %s", data_to_find, ll_contains(&list, data_to_find) ? "true\n" : "false\n");
printf("\n");
// ll_first_index
data_to_find = 10;
printf("The data %d is at node [%d]\n", data_to_find, ll_first_index(&list, data_to_find));
data_to_find = 96;
printf("The data %d is at node [%d]\n", data_to_find, ll_first_index(&list, data_to_find));
// ll_indexes
ll_add_last(&list, 25);
ll_add_first(&list, 25);
ll_insert(&list, 25, list.size);
ll_print(&list);
uint32_t *indexes = NULL;
uint32_t indexes_size = 0;
if (ll_indexes(&list, 25, &indexes, &indexes_size) == 0) {
for (int i = 0; i < indexes_size; i++) {
printf("%d ", indexes[i]);
}
printf("\n");
}
free(indexes);
if (ll_indexes(&list, 6, &indexes, &indexes_size) == 0) {
for (int i = 0; i < indexes_size; i++) {
printf("%d ", indexes[i]);
}
printf("\n");
}
free(indexes);
if (ll_indexes(&list, 7, &indexes, &indexes_size) == 0) {
for (int i = 0; i < indexes_size; i++) {
printf("%d ", indexes[i]);
}
printf("\n");
}
free(indexes);
ll_destroy(&list);
ll_destroy(&list);
return 0;
}
我对这些东西很陌生,并试图将 if 条件放在我可以测试的错误上,但是我对测试这个 API 的想法已经用完了,也许我忽略了一些事情?
在提高 API 质量之前,您首先需要检查代码并移除错误。
例如,即使是您提供的代码中的第一个函数
ll_create
也没有意义,而且会产生内存泄漏
int ll_create(linked_list_p list, void (*print_data)(uint8_t)) {
if (list == NULL) {
list = calloc(1, sizeof(linked_list_p));
return 0;
}
return -1;
}
因为退出函数后分配的内存地址丢失了
对于这个函数的调用
ll_create(&list, print_data);
函数返回
-1
.
函数的第二个参数也没有使用。
或另一个例子。目前还不清楚为什么函数
ll_destroy
在main的最后被调用了两次。
ll_destroy(&list);
ll_destroy(&list);
这会导致未定义的行为,因为函数中的尾部未设置为 NULL。