【发布时间】:2021-05-09 16:20:22
【问题描述】:
我正在研究双向链表,但遇到了问题。我将逐步粘贴部分代码,并尝试解释发生了什么。
所以我已经定义了数据类型:
typedef struct node {
void *data;
struct node *prev, *next;
} NODE;
add 函数的这一部分可能有问题。我检查了所有场景,但我不想粘贴不必要的代码。
void add(NODE **phead, NODE **ptail, void *data, int (*cmp)(const void*, const void*)){
NODE *p, *q, *new = (NODE*)calloc(1, sizeof(NODE));
new->data = data;
if(*phead == 0)
*phead = *ptail = new;
else if((*cmp)((*phead)->data, data) > 0){
new->next = *phead;
(*phead)->prev = new;
*phead = new;
}
当我调试代码时,我看到当函数指针被调用时,相同的地址被作为参数发送。
NODE *search(NODE *head, NODE *tail, const void *data, int (*cmp)(const void*, const void*)){
if(head == 0)
return 0;
while ((*cmp)(head->data, data) < 0 && (*cmp)(tail->data, data) > 0)
{
head = head->next;
tail = tail->prev;
}
if((*cmp)(head->data, data) == 0)
return head;
else if((*cmp)(tail->data, data) == 0)
return tail;
else
return 0;
}
比较函数add和search的参数是:
int cmp_str(const void *a, const void *b){
return strcmp((const char*)a, (const char*)b);
}
调用search 和add 的主函数的一部分:
int main(){
NODE *head = 0, *tail = 0;
char c, *data = (char*)calloc(20, sizeof(char));
do
{
printf("Add [A], delete [D], write [W], search [S], end [0]: ");
scanf("\n%c", &c);
if(c == 'A'){
get_string(&data);
NODE *p = search(head, tail, data, &cmp_str);
if(p){
p->data = data;
printf("Data updated!\n");
}
else{
add(&head, &tail, data, &cmp_str);
printf("Data added.\n");
}
}
所以基本上出错的地方是只保存了一个数据。在这里,我使用字符串,但数据的参数和变量是 void*。所以当我输入添加两个节点时,只保存最后输入的数据。同样在 main 中,除了第一个 p 之外,每次都由 search 函数找到,即使它不存在。正如我所说,调试器说cmp_str 接收到相同地址的两个参数,这可能暗示要找到错误所在。
【问题讨论】:
标签: c linked-list void