gpt4 book ai didi

c - C 中的链表

转载 作者:太空狗 更新时间:2023-10-29 15:45:32 25 4
gpt4 key购买 nike

我在运行这个链表实现时遇到了一些问题(包含单词作为数据)。问题是当我尝试在链接列表中打印(我插入的)单词时,我什么也没得到。我做错了什么,为此伤脑筋?我希望这不是愚蠢的事情。不管怎样,这是代码 -

typedef struct node
{
void *data;
struct node *next;
} NODE;

NODE *new_node(void *data)
{
NODE *new = malloc(sizeof(NODE));
if(new)
{
new->data = data;
new->next = NULL;
return new;
}
else
{
return NULL;
}
}

void print_list(NODE *head, void (print_fn) (void*))
{
if(head && head->next)
{
while(head->next)
{
if(print_fn)
print_fn(head->data);
else
printf("Word: %s\n", (char *)head->data);
head = head->next;
}
}
return;
}

void append(NODE **head, NODE *node)
{
NODE *tmp = *head;
if(tmp && node)
{
while(tmp->next)
tmp = tmp->next;
(*head)->next = node; /*add as last node*/
}
return;
}


NODE *create_list()
{
FILE *dict_file = fopen("trial.txt", "r");

if(dict_file)
{
NODE *head = new_node(NULL);
if(!head) return NULL;

char word[20];
int first = TRUE;
memset(word, '\0', 20);

while(fgets(word, sizeof(word), dict_file) != NULL )
{
if(first)
{
head->data = (void*)word;
first = FALSE;
}
else
{
append(&head, new_node((void*)word));
}
}
fclose(dict_file);
return head;
}
else
{
printf("ERROR: File not found");
return NULL;
}
}

int main(int argc, char *argv[])
{
NODE *head = create_list();

if(!head)
{
printf("ERROR: Either malloc() failed or data not found\n");
return FALSE;
}
else
{
print_list(head, NULL);
return TRUE;
}
}

最佳答案

这已经变成了一个很长的答案。不要把这当回事,但你犯了很多新手错误。我在大学遇到过很多人,我帮助他们学习了 C 语言和一般编程,所以我已经习惯了注意这些事情。

我能找到的重要问题

  • 您将指向堆栈变量的指针分配给 words
    这是非常糟糕的,因为一旦执行脱离创建它的函数,该值就会被覆盖。 解决方案:将该变量的内容复制到堆变量中。

  • 您的append 函数有问题
    它将附加元素添加到第二个位置而不是最后一个位置。请注意,您最后也不需要 return 。要求将双指针作为 append 方法的输入也是没有意义的。此外,在将 head 分配给 tmp 之后,检查 tmp 是否符合 NULL 也是徒劳的,因为它不会是 NULL 如果 head 不是 NULL。此外,我还建议根据 NULL 检查新节点。如果它是 NULL,则可以避免迭代整个集合。

  • create_list 函数不是最优的
    首先,区分第一种情况和其他情况是徒劳的。引入另一个指针(在我的代码中称为 current)将消除检查它是否是第一个的需要。接下来,您总是在head 上调用append 函数,因此您总是需要遍历整个集合。这也可以通过引入 current 变量来优化。 (在开始时,应为其分配 head 的值。)

  • print_list 函数错误
    如果只有一个节点,它不会打印任何内容。它还冗余地检查指针是否为空。 (循环的开头也会检查它。)此 void 函数末尾的 return 语句也是不必要的。

  • 不使用时应该释放内存
    @Baltasarq 在他的回答中写了一个很好的 clear 函数,你应该使用它。 :)

不是很严重的错误,但你应该意识到它们

  • 你不应该使用 void* 而不是 char*如果你知道NODE结构的data成员是要存储字符的,为什么还要使用void*呢?这是不好的做法! (当然,除非你有充分的理由。)

  • 使用 new 词作为变量名会使您的代码不符合 C++。因此,我建议不要这样做。

  • 请采用更好的编码风格 - 这将使您的代码更易于阅读

  • 不一致:如果在 print_list 中您没有分配一个新变量来遍历集合(就像您在 中使用 tmp 变量一样) append) 那么将参数命名为 head 是错误的。 (我在代码中将其重命名为 node。)

这里是固定代码

(请注意,可能会有小的语法错误,因为我在没有实际测试的情况下将代码输入浏览器。)

#include <string.h>
#include <stdlib.h>
#include <stdio.h>

typedef struct node
{
void *data;
struct node *next;
} NODE;

NODE *new_node(void *data)
{
NODE *newNode = (NODE*)malloc(sizeof(NODE));
if (newNode)
{
newNode->data = data;
newNode->next = NULL;
return newNode;
}
return NULL;
}

void append(NODE *head, NODE *node)
{
if (head && node)
{
NODE *tmp = head;
while (tmp->next)
tmp = tmp->next;
tmp->next = node; /* add as last node */
}
}

void print_list(NODE *node, void (print_fn) (void*))
{
while (node)
{
if (print_fn)
print_fn(node->data);
else
printf("Word: %s\n", (char *)node->data);

node = node->next;
}
}

NODE *create_list()
{
FILE *dict_file = fopen("trial.txt", "r");

if (dict_file)
{
NODE *head = NULL;
NODE *current = head;

char word[20];
memset(word, '\0', 20);

while (fgets(word, sizeof(word), dict_file))
{
// Creating a variable on the heap
char *data = calloc(sizeof(word) + 1, sizeof(char));
// Copying the contents of words to it
strcpy(data, word);

append(current, new_node((void*)data));
if (current->next)
current = current->next
}
fclose(dict_file);
return head;
}
else
{
printf("ERROR: File not found");
}
return NULL;
}

int main(int argc, char *argv[])
{
NODE *head = create_list();

if (!head)
{
printf("ERROR: Either malloc() failed or data not found\n");
}
else
{
print_list(head, NULL);
}
return 0;
}

关于c - C 中的链表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3727569/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com