简单链表无法打印
simple linked list failing to print
我正在学习如何制作链表,但它根本无法打印出任何内容,我不明白为什么???请帮忙。我相信这与我的指示有关,但我不知道它是什么。
#include <stdio.h>
#include <stdlib.h>
// typedef is used to give a data type a new name
typedef struct node * link ;// link is now type struct node pointer
/*
typedef allows us to say "link ptr"
instead of "struct node * ptr"
*/
struct node{
int item ;// this is the data
link next ;//same as struct node * next, next is a pointer
};
void printAll(link head); // print a linked list , starting at link head
void addFirst(link ptr, int val ); // add a node with given value to a list
link removeLast(link ptr); // removes and returns the last element in the link
//prints the link
void printAll(link head){
link ptr = head;
printf("\nPrinting Linked List:\n");
while(ptr != NULL){
printf(" %d ", (*ptr).item);
ptr = (*ptr).next;// same as ptr->next
}
printf("\n");
}
//adds to the head of the link
void addFirst(link ptr, int val ){
link tmp = malloc(sizeof(struct node));// allocates memory for the node
tmp->item = val;
tmp->next = ptr;
ptr = tmp;
}
// testing
int main(void) {
link head = NULL;// same as struct node * head, head is a pointer type
//populating list
for(int i = 0; i<3; i++){
addFirst(head, i);
}
printAll(head);
return 0;
}
输出:
正在打印链表:
进程返回 0 (0x0) 执行时间:0.059 秒
按任意键继续
这是因为您向函数传递了一个空指针,而退出循环的条件是该指针为空,所以什么也没有发生。
您的 addFirst
函数采用指针的值,但它不能修改您在 main() 内部声明的 head
。
要修改 head
,您需要将指针传递给 link,然后您可以取消引用该指针以访问您的 head
,然后您可以更改它。
void addFirst(link *ptr, int val ){
link tmp = malloc(sizeof(struct node));// allocates memory for the node
tmp->item = val;
tmp->next = *ptr;
*ptr = tmp;
}
现在可以更改头指针了。只要记住在调用函数时将地址传递给它即可。 addFirst(&head,i)
在for循环中
for(int i = 0; i<3; i++){
addFirst(head, i);
}
你创建了一堆指向 NULL
的指针。 head
永远不会改变,因为指针本身已被传递 "by value"。例如。 head
被复制并且在 addFirst
中对指针本身的所有修改在外部不可见。
这与说 int
相同。想象一下 void foo(int x);
。此函数对 x 所做的任何事情在外部都是不可见的。
但是 link ptr
指向的内存的变化当然是可见的。
例如这一行什么都不做:
tmp->next = ptr;
ptr = tmp; <=== this line
}
您可以通过多种方式解决此问题。一种是从 addFirst
到 return 新节点,另一种是使 link ptr
成为指向指针的指针:link *ptr
。因为在这种情况下你想改变指针值(不是指针值):
//link *ptr here a pointer to pointer
void addFirst(link * ptr, int val ){
link tmp = malloc(sizeof(struct node));// allocates memory for the node
tmp->item = val;
tmp->next = *ptr; //<<changed
*ptr = tmp; //<<changed
}
别忘了更新上面的声明。和电话:
void addFirst(link * ptr, int val ); // add a node with given value to a list
...
for(int i = 0; i<3; i++){
addFirst(&head, i);
}
然后这段代码产生:
Printing Linked List:
2 1 0
已添加:
重要的是要了解使用链表需要使用两种不同类型的数据。
首先是 struct node
,您使用 link
s 传递此类数据。
其次是head
。这是指向第一个节点的指针。当您想修改头部时,您会发现它不是 "node"。这是另一回事。它是列表中第一个节点的 "name"。这个名字本身就是一个指向节点的指针。查看 head
的内存布局与列表本身有何不同。
head[8 bytes]->node1[16 bytes]->node2[16 bytes]->...->nodek[16 bytes]->NULL;
顺便说一下 - 这里唯一有词汇名称的是 head
。所有节点都没有名称,可以通过 node->next
语法访问。
你也可以在这里想象另一个指针,link last
将指向 nodek
。同样,这将具有与节点本身不同的内存布局。如果你想在函数中修改它,你需要将函数指针传递给它(e.g.pointer 到指针)。
指针和它指向的数据是不同的东西。在您看来,您需要将它们分开。指针类似于 int
或 float
。它被传递 "by value" 给函数。是的 link ptr
已经是指针,它允许您更新它指向的数据。但是,指针本身是按值传递的,并且对指针的更新(在您的情况下 ptr=tmp
)在外部不可见。
(*ptr).next=xxx
当然是可见的,因为数据已更新(不是指针)。这意味着你需要做一个额外的步骤 - 使你的指针在功能之外可见的变化,例如将指针本身 (head
) 转换为另一个指针的数据,例如使用 struct node **ptr
(这里的第一颗星表示这是指向节点的指针,第二颗星将该指针转换为另一个指针的数据。
我正在学习如何制作链表,但它根本无法打印出任何内容,我不明白为什么???请帮忙。我相信这与我的指示有关,但我不知道它是什么。
#include <stdio.h>
#include <stdlib.h>
// typedef is used to give a data type a new name
typedef struct node * link ;// link is now type struct node pointer
/*
typedef allows us to say "link ptr"
instead of "struct node * ptr"
*/
struct node{
int item ;// this is the data
link next ;//same as struct node * next, next is a pointer
};
void printAll(link head); // print a linked list , starting at link head
void addFirst(link ptr, int val ); // add a node with given value to a list
link removeLast(link ptr); // removes and returns the last element in the link
//prints the link
void printAll(link head){
link ptr = head;
printf("\nPrinting Linked List:\n");
while(ptr != NULL){
printf(" %d ", (*ptr).item);
ptr = (*ptr).next;// same as ptr->next
}
printf("\n");
}
//adds to the head of the link
void addFirst(link ptr, int val ){
link tmp = malloc(sizeof(struct node));// allocates memory for the node
tmp->item = val;
tmp->next = ptr;
ptr = tmp;
}
// testing
int main(void) {
link head = NULL;// same as struct node * head, head is a pointer type
//populating list
for(int i = 0; i<3; i++){
addFirst(head, i);
}
printAll(head);
return 0;
}
输出:
正在打印链表:
进程返回 0 (0x0) 执行时间:0.059 秒
按任意键继续
这是因为您向函数传递了一个空指针,而退出循环的条件是该指针为空,所以什么也没有发生。
您的 addFirst
函数采用指针的值,但它不能修改您在 main() 内部声明的 head
。
要修改 head
,您需要将指针传递给 link,然后您可以取消引用该指针以访问您的 head
,然后您可以更改它。
void addFirst(link *ptr, int val ){
link tmp = malloc(sizeof(struct node));// allocates memory for the node
tmp->item = val;
tmp->next = *ptr;
*ptr = tmp;
}
现在可以更改头指针了。只要记住在调用函数时将地址传递给它即可。 addFirst(&head,i)
在for循环中
for(int i = 0; i<3; i++){
addFirst(head, i);
}
你创建了一堆指向 NULL
的指针。 head
永远不会改变,因为指针本身已被传递 "by value"。例如。 head
被复制并且在 addFirst
中对指针本身的所有修改在外部不可见。
这与说 int
相同。想象一下 void foo(int x);
。此函数对 x 所做的任何事情在外部都是不可见的。
但是 link ptr
指向的内存的变化当然是可见的。
例如这一行什么都不做:
tmp->next = ptr;
ptr = tmp; <=== this line
}
您可以通过多种方式解决此问题。一种是从 addFirst
到 return 新节点,另一种是使 link ptr
成为指向指针的指针:link *ptr
。因为在这种情况下你想改变指针值(不是指针值):
//link *ptr here a pointer to pointer
void addFirst(link * ptr, int val ){
link tmp = malloc(sizeof(struct node));// allocates memory for the node
tmp->item = val;
tmp->next = *ptr; //<<changed
*ptr = tmp; //<<changed
}
别忘了更新上面的声明。和电话:
void addFirst(link * ptr, int val ); // add a node with given value to a list
...
for(int i = 0; i<3; i++){
addFirst(&head, i);
}
然后这段代码产生:
Printing Linked List:
2 1 0
已添加: 重要的是要了解使用链表需要使用两种不同类型的数据。
首先是 struct node
,您使用 link
s 传递此类数据。
其次是head
。这是指向第一个节点的指针。当您想修改头部时,您会发现它不是 "node"。这是另一回事。它是列表中第一个节点的 "name"。这个名字本身就是一个指向节点的指针。查看 head
的内存布局与列表本身有何不同。
head[8 bytes]->node1[16 bytes]->node2[16 bytes]->...->nodek[16 bytes]->NULL;
顺便说一下 - 这里唯一有词汇名称的是 head
。所有节点都没有名称,可以通过 node->next
语法访问。
你也可以在这里想象另一个指针,link last
将指向 nodek
。同样,这将具有与节点本身不同的内存布局。如果你想在函数中修改它,你需要将函数指针传递给它(e.g.pointer 到指针)。
指针和它指向的数据是不同的东西。在您看来,您需要将它们分开。指针类似于 int
或 float
。它被传递 "by value" 给函数。是的 link ptr
已经是指针,它允许您更新它指向的数据。但是,指针本身是按值传递的,并且对指针的更新(在您的情况下 ptr=tmp
)在外部不可见。
(*ptr).next=xxx
当然是可见的,因为数据已更新(不是指针)。这意味着你需要做一个额外的步骤 - 使你的指针在功能之外可见的变化,例如将指针本身 (head
) 转换为另一个指针的数据,例如使用 struct node **ptr
(这里的第一颗星表示这是指向节点的指针,第二颗星将该指针转换为另一个指针的数据。