This commit is contained in:
2026-08-30 01:48:03 +08:00
parent 84ebd52c24
commit 7940b67827
170 changed files with 2704 additions and 21276 deletions
+57 -48
View File
@@ -1,68 +1,77 @@
#include "c_LinkList.h"
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include "c_Test.h"
typedef struct {
char name[4];
int score;
} Student_t;
int main() {
printf("開始執行 c_LinkList 測試用例...\n");
int id;
int is_processed;
} DataEvent_t;
TEST_CASE(test_nosentinel_link_list_and_iterator_flow) {
c_LinkList_t list;
c_LinkList_Init(&list, sizeof(Student_t));
Student_t s1 = {"AAA", 80};
Student_t s2 = {"BBB", 90};
Student_t s3 = {"CCC", 95};
// 验证你的新 Init API
ASSERT_INT_EQ(C_ERR_OK, c_LinkList_Init(&list, sizeof(DataEvent_t), NULL));
ASSERT_TRUE(0==list.head); // 确认 head 严格等于 0
ASSERT_TRUE(c_LinkList_IsEmpty(&list));
// 1. 測試新增 (頭插法預期順序: CCC -> BBB -> AAA)
c_LinkList_Add(&list, &s1);
c_LinkList_Add(&list, &s2);
c_LinkList_Add(&list, &s3);
assert(list.size == 3);
DataEvent_t e1 = { .id = 10, .is_processed = 1 }; // 已处理,迭代时擦除
DataEvent_t e2 = { .id = 20, .is_processed = 0 };
DataEvent_t e3 = { .id = 30, .is_processed = 1 }; // 已处理,边界连续擦除
DataEvent_t e4 = { .id = 40, .is_processed = 0 };
// 2. 測試迭代器走訪
c_LinkListIter_t iter;
c_LinkListIter_Init(&iter, &list);
// 1. 验证 AddTail 与 AddHead 在无哨兵下的完美二级指针闭环运转
ASSERT_INT_EQ(C_ERR_OK, c_LinkList_AddTail(&list, &e1)); // Head -> 10
ASSERT_INT_EQ(C_ERR_OK, c_LinkList_AddTail(&list, &e2)); // Head -> 10 -> 20
ASSERT_INT_EQ(C_ERR_OK, c_LinkList_AddTail(&list, &e3)); // Head -> 10 -> 20 -> 30
ASSERT_INT_EQ(C_ERR_OK, c_LinkList_AddHead(&list, &e4)); // 头插 40, 拓扑进化为: Head -> 40 -> 10 -> 20 -> 30
printf("當前串列內容:\n");
while (c_LinkListIter_HasNext(&iter)) {
Student_t* s = (Student_t*)c_LinkListIter_Next(&iter);
printf(" 學生: %s, 分數: %d\n", s->name, s->score);
}
ASSERT_INT_EQ(4, c_LinkList_Size(&list));
// 3. 測試一般刪除 (Remove - 透過二進位資料比對刪除 "BBB")
Student_t target_remove = {"BBB", 90};
c_err_t err = c_LinkList_Remove(&list, &target_remove);
assert(err == C_ERR_OK);
assert(list.size == 2);
// 2. 启动极致无哨兵二级指针迭代清理流
c_LinkListIter_t it;
c_LinkListIter_Init(&it, &list);
// 4. 測試迭代器走訪並刪除 (Iter_Remove)
c_LinkListIter_Init(&iter, &list);
while (c_LinkListIter_HasNext(&iter)) {
Student_t* s = (Student_t*)c_LinkListIter_Get(&iter);
if (s->score == 80) { // 找到分數 80 的學生 (AAA)
c_LinkListIter_Remove(&iter);
printf("[Log] 迭代器成功刪除了分數為 80 的學生\n");
} else {
c_LinkListIter_Next(&iter);
int scanned = 0;
while (c_LinkListIter_HasNext(&it)) {
DataEvent_t* ev = (DataEvent_t*)c_LinkListIter_Get(&it);
ASSERT_PTR_NOT_NULL(ev);
scanned++;
if (ev->is_processed) {
// 自主剔除:当剔除 e1(10) 时,由于它是当时的第二项,其前驱是 e4 的 next
// 当剔除头项或末尾项时,二级指针无需任何 if 分支,在硬件层面一路展平串联
c_LinkListIter_Remove(&it);
continue;
}
c_LinkListIter_Next(&it);
}
assert(list.size == 1);
// 5. 驗證最後留下來的是否為 CCC
c_LinkListIter_Init(&iter, &list);
Student_t* final_s = (Student_t*)c_LinkListIter_Get(&iter);
assert(strcmp(final_s->name, "CCC") == 0);
// 3. 终极断言验证
ASSERT_INT_EQ(4, scanned);
ASSERT_INT_EQ(2, c_LinkList_Size(&list)); // 2 个已处理的脏数据被定点抹杀
// 严苛验证存活项的相对物理连续性 (剩下了 40 和 20)
DataEvent_t* r0 = (DataEvent_t*)c_LinkList_Get(&list, 0);
DataEvent_t* r1 = (DataEvent_t*)c_LinkList_Get(&list, 1);
ASSERT_PTR_NOT_NULL(r0);
ASSERT_PTR_NOT_NULL(r1);
ASSERT_INT_EQ(40, r0->id);
ASSERT_INT_EQ(20, r1->id);
// 校验 naked 单链表的物理封底指针是否干净合拢
ASSERT_TRUE(c_LinkNode_Get(list.head) == r0); // list.head 应该妥妥地挂在 40 节点上
ASSERT_TRUE(c_LinkNode_Get(list.head->next) == r1); // 40 的下一个由于 10 死了,直接跨越连到了 20 节点
ASSERT_TRUE(c_LinkNode_Get(list.head->next->next) == NULL); // 20 作为最后一个节点,其 next 指针域必须被强制完美封底为 NULL
// 銷毀資源
c_LinkList_Destroy(&list);
assert(list.head == NULL);
assert(list.size == 0);
}
printf("所有測試成功通過!\n");
return 0;
int main(void) {
TEST_START(C_NoSentinel_LinkList_System_Tests);
RUN_TEST(test_nosentinel_link_list_and_iterator_flow);
TEST_REPORT();
RETURN_TEST_STATUS;
}