c - 使用双指针在 C 中插入链表
问题描述
嗨,我是学习链接列表的新手,我创建了这个示例程序,但它没有填充所有列表,只有最后两个被填充(或者这些覆盖了第一个链接元素)
有人可以帮我解决问题的原因吗?
#include<stdio.h>
#include<stdlib.h>
struct node {
int data;
struct node *link;
};
void appendNode(int data, struct node **ptr) {
struct node *newnode = (struct node*)malloc(sizeof(struct node));
newnode->data = data;
newnode->link = NULL;
if(*ptr == NULL) {
*ptr = newnode;
} else {
while((*ptr)->link != NULL ) {
*ptr = (*ptr)->link;
}
(*ptr)->link = newnode;
}
}
void printList(struct node *node)
{
while (node != NULL)
{
printf(" %d ", node->data);
node = node->link;
}
}
int main() {
struct node *head = NULL ;
appendNode(23,&head);
appendNode(45,&head);
appendNode(32,&head);
appendNode(11,&head);
appendNode(98,&head);
printList(head);
}
红外打印
11 98
是什么导致了这里的问题?
解决方案
您的问题是您正在使用[1]中的指针本身进行迭代。每次您将某些内容分配给时,这都会更改列表地址,例如appendNode
*ptr
*ptr = newnode;
...
*ptr = (*ptr)->link;
每次*ptr
分配列表地址都会更改(如appendNode
和 中所示main()
)
Your list operations are correct, all you need to do is use a temporary pointer to iterate over the list (iter
below)
void appendNode (int data, struct node **ptr) {
struct node *newnode = malloc (sizeof *newnode),
*iter = *ptr;
if (!newnode) { /* VALIDATE every allocation */
perror ("malloc-newnode");
exit (EXIT_FAILURE);
}
newnode->data = data;
newnode->link = NULL;
if (iter == NULL) {
*ptr = newnode;
}
else {
while (iter->link != NULL) {
iter = iter->link;
}
iter->link = newnode;
}
}
(note the use of the dereferenced pointer used with sizeof
to set the type-size. If you use the dereferenced pointer to set the size, you eliminate any mistake in setting the actual type needed. Also, if you allocate -- you must validate -- every time)
With that change (and the following change to printList
)
void printList (struct node *node)
{
while (node != NULL)
{
printf(" %d ", node->data);
node = node->link;
}
putchar ('\n'); /* tidy up with newline */
}
Your list works just fine, e.g.
Example Use/Output
$ ./bin/lllast2
23 45 32 11 98
footnotes:
1. While not an error, C generally avoids the use of camelCase
or MixedCase
variable names in favor of all lower-case while reserving upper-case names for use with macros and constants. It is a matter of style -- so it is completely up to you, but failing to follow it can lead to the wrong first impression in some circles.
推荐阅读
- node.js - 错误 413 请求实体太大 docker 节点
- mysql - cloudshell 和 google sql 遇到问题
- python - 停止函数更改原始列表
- javascript - 变量更改时不执行 BehaviorSubject
- sql - 基于另一个表更新
- perl - 在 Perl 中从文件转换日期
- c++ - macOS 上缺少 Qt 库
- ionic4 - 如何在 Ionic 4 中搜索多个项目?
- javascript - 如何为实际上更改菜单选项语言的 wordpress 网站创建语言切换?
- c# - 如何使用“InternalsVisibleTo”从 XAML 访问另一个程序集中的内部类转换器