链表遍历跳过第一个元素
Linked list traversal skips first element
我有一个 C 程序可以在链表的开头插入元素,但是当我尝试打印元素时,它总是跳过第一个元素。有人可以指出我在我的程序中做错了什么吗?
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
void PrintElements();
void InsertElement(int x);
struct node
{
int data;
struct node* next;
};
struct node* HEAD;
struct node* temp;
struct node* temp1;
void PrintElements()
{
temp1=HEAD;
while(temp1->next!=NULL)
{
printf("\n\r Data %d\n\r",temp1->data);
printf("\n\r Address %x\n\r",temp1->next);
temp1=temp1->next;
}
}
void InsertElement(int x)
{
struct node* temp=(struct node*)malloc(sizeof(struct node));
temp->data=x;
temp->next=HEAD;
HEAD=temp;
}
int main()
{
int i, x;
int n; //n stores the number of elements to be added to the linked list
HEAD=NULL; //Assigning HEAD to null when there are no elements in the list
printf("Enter the number of elements\n");
scanf("%d",&n);
for(i=0;i<n;i++)
{
printf("\n\rEnter the number");
scanf("%d",&x);
InsertElement(x);
PrintElements();
}
return 0;
}
当我更改以下行时
while(temp1->next!=NULL)
到
while(temp1!=NULL)
程序运行正常,但我仍然不明白为什么。
while(temp1->next!=NULL)
将此更改为
while(temp1 != NULL)
它应该可以正常工作。
原因:我认为它不会打印您输入的第一个元素。
示例:输入:1 2 3
链接列表形成为:3 -> 2 -> 1 -> NULL
使用的符号:每个数字都是data
,箭头表示指针next
。
然后当你开始循环时,对于每次迭代:
temp1
指向3
的地址
temp1 -> next != NULL
(正确,因为 temp1 -> next
指向 2
的地址)
打印 3
和 temp1
现在指向 2
的地址
temp1 -> next != NULL
(正确,因为 temp1 -> next
指向 1
的地址)
打印 2
和 temp1
现在指向 1
的地址
temp1 -> next != NULL
这变成了 False 因为 temp1
指向 1
的地址并且 temp1 -> next
是无效的。
所以我们永远不会进入循环来打印 1
。
所以正确的做法是使用 temp1 != NULL
因为这将消除上述错误。
您描述的问题可以通过将 PrintElements()
函数中的控制表达式更改为 temp1 != NULL
来解决。这样,如果 temp1
指向一个节点,则打印 data
和 next
字段,并继续循环直到没有更多节点。当遍历一个链表时,当你查看下一个节点来决定你将对当前节点做什么时,通常会让人感到困惑。但是这段代码还有其他问题。
首先,在main()
中声明struct
指针并将它们传递给函数会更好,而不是将它们声明为全局变量。您应该尽可能检查您调用的函数的 return 值。您应该检查 scanf()
以确保输入符合预期;这也提供了一种控制输入循环的方法,用户无需在输入数据之前明确输入计数。您还应该通过调用 malloc()
检查值 return 以捕获分配错误。当在下一行取消引用 temp
时,代码中的此类分配错误会导致未定义的行为。
您应该 free
所有内存分配,每次调用 malloc()
一个 free()
。当您在函数 PrintElements()
中打印列表中 next
节点的地址时,您调用了未定义的行为。要打印指针的值,您应该使用 %p
格式说明符,并且必须将指针转换为 (void *)
。终于不用#include <malloc.h>
了; stdlib.h
满足您的需求。
这是您的代码的修改版本,它实现了建议的更改。请注意,在分配错误的情况下,一条消息将打印到 stderr
,程序将打印到 exit
s。对 malloc()
的调用已被简化:没有理由在 C 中强制转换 malloc()
的结果,最好使用分配内存的指针的名称来代替给 malloc()
的参数中的显式类型。 new_node
被 returned 到调用函数,其中指向列表 head
的指针被重新分配以指向 new_node
.
#include <stdio.h>
#include <stdlib.h>
struct node
{
int data;
struct node* next;
};
void print_elements(struct node *start);
struct node * insert_element(int x, struct node *head);
int main(void)
{
struct node* head = NULL;
struct node* curr = NULL;
int x;
/* Read data into linked list */
printf("Enter the first integer (q to quit): ");
while (scanf("%d", &x) == 1) {
head = insert_element(x, head);
print_elements(head);
printf("Enter another integer (q to quit): ");
}
/* Free allocated memory */
while (head) {
curr = head;
head = curr->next;
free(curr);
}
return 0;
}
void print_elements(struct node *curr)
{
while(curr) {
printf(" Data: %d\n",curr->data);
printf("Address: %p\n\n",(void *) curr->next);
curr = curr->next;
}
}
struct node * insert_element(int x, struct node *head)
{
struct node *new_node = malloc(sizeof(*new_node));
if (new_node == NULL) {
fprintf(stderr, "Allocation error in function insert_element()\n");
exit(EXIT_FAILURE);
}
new_node->data = x;
new_node->next = head;
return new_node;
}
我有一个 C 程序可以在链表的开头插入元素,但是当我尝试打印元素时,它总是跳过第一个元素。有人可以指出我在我的程序中做错了什么吗?
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
void PrintElements();
void InsertElement(int x);
struct node
{
int data;
struct node* next;
};
struct node* HEAD;
struct node* temp;
struct node* temp1;
void PrintElements()
{
temp1=HEAD;
while(temp1->next!=NULL)
{
printf("\n\r Data %d\n\r",temp1->data);
printf("\n\r Address %x\n\r",temp1->next);
temp1=temp1->next;
}
}
void InsertElement(int x)
{
struct node* temp=(struct node*)malloc(sizeof(struct node));
temp->data=x;
temp->next=HEAD;
HEAD=temp;
}
int main()
{
int i, x;
int n; //n stores the number of elements to be added to the linked list
HEAD=NULL; //Assigning HEAD to null when there are no elements in the list
printf("Enter the number of elements\n");
scanf("%d",&n);
for(i=0;i<n;i++)
{
printf("\n\rEnter the number");
scanf("%d",&x);
InsertElement(x);
PrintElements();
}
return 0;
}
当我更改以下行时
while(temp1->next!=NULL)
到
while(temp1!=NULL)
程序运行正常,但我仍然不明白为什么。
while(temp1->next!=NULL)
将此更改为
while(temp1 != NULL)
它应该可以正常工作。
原因:我认为它不会打印您输入的第一个元素。
示例:输入:1 2 3
链接列表形成为:3 -> 2 -> 1 -> NULL
使用的符号:每个数字都是data
,箭头表示指针next
。
然后当你开始循环时,对于每次迭代:
temp1
指向3
的地址
temp1 -> next != NULL
(正确,因为temp1 -> next
指向2
的地址)打印
3
和temp1
现在指向2
的地址
temp1 -> next != NULL
(正确,因为temp1 -> next
指向1
的地址)打印
2
和temp1
现在指向1
的地址
temp1 -> next != NULL
这变成了 False 因为temp1
指向1
的地址并且temp1 -> next
是无效的。
所以我们永远不会进入循环来打印 1
。
所以正确的做法是使用 temp1 != NULL
因为这将消除上述错误。
您描述的问题可以通过将 PrintElements()
函数中的控制表达式更改为 temp1 != NULL
来解决。这样,如果 temp1
指向一个节点,则打印 data
和 next
字段,并继续循环直到没有更多节点。当遍历一个链表时,当你查看下一个节点来决定你将对当前节点做什么时,通常会让人感到困惑。但是这段代码还有其他问题。
首先,在main()
中声明struct
指针并将它们传递给函数会更好,而不是将它们声明为全局变量。您应该尽可能检查您调用的函数的 return 值。您应该检查 scanf()
以确保输入符合预期;这也提供了一种控制输入循环的方法,用户无需在输入数据之前明确输入计数。您还应该通过调用 malloc()
检查值 return 以捕获分配错误。当在下一行取消引用 temp
时,代码中的此类分配错误会导致未定义的行为。
您应该 free
所有内存分配,每次调用 malloc()
一个 free()
。当您在函数 PrintElements()
中打印列表中 next
节点的地址时,您调用了未定义的行为。要打印指针的值,您应该使用 %p
格式说明符,并且必须将指针转换为 (void *)
。终于不用#include <malloc.h>
了; stdlib.h
满足您的需求。
这是您的代码的修改版本,它实现了建议的更改。请注意,在分配错误的情况下,一条消息将打印到 stderr
,程序将打印到 exit
s。对 malloc()
的调用已被简化:没有理由在 C 中强制转换 malloc()
的结果,最好使用分配内存的指针的名称来代替给 malloc()
的参数中的显式类型。 new_node
被 returned 到调用函数,其中指向列表 head
的指针被重新分配以指向 new_node
.
#include <stdio.h>
#include <stdlib.h>
struct node
{
int data;
struct node* next;
};
void print_elements(struct node *start);
struct node * insert_element(int x, struct node *head);
int main(void)
{
struct node* head = NULL;
struct node* curr = NULL;
int x;
/* Read data into linked list */
printf("Enter the first integer (q to quit): ");
while (scanf("%d", &x) == 1) {
head = insert_element(x, head);
print_elements(head);
printf("Enter another integer (q to quit): ");
}
/* Free allocated memory */
while (head) {
curr = head;
head = curr->next;
free(curr);
}
return 0;
}
void print_elements(struct node *curr)
{
while(curr) {
printf(" Data: %d\n",curr->data);
printf("Address: %p\n\n",(void *) curr->next);
curr = curr->next;
}
}
struct node * insert_element(int x, struct node *head)
{
struct node *new_node = malloc(sizeof(*new_node));
if (new_node == NULL) {
fprintf(stderr, "Allocation error in function insert_element()\n");
exit(EXIT_FAILURE);
}
new_node->data = x;
new_node->next = head;
return new_node;
}