C中的字符串链表
Posted
技术标签:
【中文标题】C中的字符串链表【英文标题】:linked list of strings in C 【发布时间】:2016-07-23 12:49:54 【问题描述】:我正在尝试在 C 中创建一个字符串链接列表,但在将第一个节点添加到列表中时遇到了问题。无论出于何种原因,即使我将 head 变量引用到 newNode,我的程序也会打印 NULL,但它不会将字符串从 struct 指针复制到 struct 指针。任何帮助表示赞赏。谢谢!
#include "stdafx.h"
#include <stdlib.h>
#include <string.h>
typedef struct stringData
char *s;
struct stringData *next;
Node;
Node *createNode(char *s)
Node *newNode = (Node *)malloc(sizeof(Node));
newNode->s = s;
newNode->next = NULL;
return newNode;
void insert(Node *head, Node *newNode)
if (head == NULL)
head->s = newNode->s;
head = newNode;
void printList(Node *head)
while (head != NULL)
printf("%s\n", head->s);
head = head->next;
int main()
Node *head = createNode(NULL);
Node *a = createNode("A");
insert(head, a);
printList(head);
return 0;
【问题讨论】:
if (head == NULL) head->s = newNode->s;
指针不能这样工作。如果head
没有指向任何东西,你就不能碰head->anything
,它不存在。
所有其他链表帖子(有数千个)都有“仅修改本地头部”错误:(
由于您的代码不正确,不清楚您是将新节点插入到列表的开头还是列表的末尾。如果您将新节点插入到列表的开头,printList
将按照它们插入的相反顺序(LIFO 顺序)打印字符串。如果您将新节点插入到列表的末尾,printList
将按照它们插入的顺序(FIFO 顺序)打印字符串。对于(单个)链表的 LIFO 排序,通常有一个变量指向链表的第一个(头)节点,另一个变量指向最后一个(尾)节点。
【参考方案1】:
这是代码的修改版本,它给出了在列表开头和结尾插入新节点的示例。事实上,insert
函数可用于在列表中的任何位置插入一个新节点,因为它只需要一个指向链接的指针和一个指向要插入的节点的指针。
#include <stdlib.h>
#include <stdio.h>
typedef struct stringData
char *s;
struct stringData *next;
Node;
Node *createNode(char *s)
Node *newNode = (Node *)malloc(sizeof(Node));
newNode->s = s;
newNode->next = NULL;
return newNode;
void insert(Node **link, Node *newNode)
newNode->next = *link;
*link = newNode;
void printList(Node *head)
while (head != NULL)
printf("%s\n", head->s);
head = head->next;
int main(void)
Node *head = NULL;
Node *tail = NULL;
Node *n;
n = createNode("B");
// First node at start of list - head is updated.
insert(&head, n);
// First node is also the tail.
tail = n;
n = createNode("A");
// Insert node at start of list - head is updated.
insert(&head, n);
n = createNode("C");
// Insert node at end of list.
insert(&tail->next, n);
// Update tail.
tail = n;
printList(head);
return 0;
【讨论】:
【参考方案2】:下面的代码sn-p是错误的:
void insert(Node *head, Node *newNode) ...
...
insert(head, a);
您需要通过引用传递指针。目前您正在更改本地副本(参数)。
修复
将您的insert
更改为:
void insert(Node **head, Node *newNode) ...
并调用为:
insert(&head, a);
还有什么至少insert
(并且可能)更多的功能不是万无一失的(保证空指针取消引用,else
大小写未处理等)。您需要调试和修复许多此类情况。在编码之前在纸上正确地使用您的方法可能会有所帮助。
【讨论】:
上升了。我同意,但该功能需要做的工作远不止这些。它直接取消引用现在的 NULL 指针,并且在非 null 时什么也不做(有或没有传递引用的解决方案)。 @WhozCraig 对,订单不好,else
案例的处理缺失。但是后来我想提示 OP 并帮助他修复代码而不是修复代码。但是,是的。我会在回答中提到这一点。
我认为这根本不是意图。这只是一个糟糕的参数名称“head”。他不想修改head
——这是一个虚拟头部列表,他打算修改head->next
。
@paddy 那么head = newNode;
的目的是什么?
我确定他们的意思是head->next = newNode
。但也许你是对的。也许它只是看起来像一个傻瓜列表,而实际上它是你所想的。代码可以采用任何一种方式。 printList
函数表明它不是假头。 insert
函数显示完全不了解任何一种列表样式。以上是关于C中的字符串链表的主要内容,如果未能解决你的问题,请参考以下文章