gpt4 book ai didi

c - 我的函数不记住链表的头

转载 作者:行者123 更新时间:2023-11-30 15:08:05 26 4
gpt4 key购买 nike

我要做一个链表的程序,有很多功能,比如删除、添加和修改数字。

在我的代码中,当我在函数中放入一个数字并选择 1 时,之后当我想显示所有数字时,我将 head 放入参数中,但我在 Visual Studio 中看到函数的参数没有有什么。我该怎么做才能在我的函数 Displaynbr

中的参数中传递链表的头
#include <stdio.h>
#include <stdlib.h>

struct Mynbr
{
int nbr;
struct Mynbr* next;
} typedef Mynbr;

void Menu();
void choiceMenu(int choice, Mynbr* first);
Mynbr* Addnumber(Mynbr* first);
void Displaynbr(Mynbr* first);

int main(void)
{
Mynbr* head = NULL;
int choice = 0;

while (choice!=5)
{
Menu();
printf("Your choice : "); scanf("%d", &choice);
choiceMenu(choice, head);
}
system("PAUSE");
return 0;
}

void Menu()
{
printf("\n1.Add number to the list\n");
printf("2.Delete number from the list\n");
printf("3.Search number in the list\n");
printf("4.Display all the numbers from the list\n");
printf("5.Exit\n");
}

void choiceMenu(int choice, Mynbr* first)
{
switch (choice)
{
case 1:
Addnumber(first);
break;
case 2:
break;
case 3:
break;
case 4:
Displaynbr(first);
break;
case 5:
break;
}
}

Mynbr* Addnumber(Mynbr* first)
{
printf("\n===Function to add a number===\n");
Mynbr* head_nbr = first;
if (!head_nbr)
{
head_nbr = (Mynbr*)malloc(sizeof(Mynbr));
printf("Enter a number :"); scanf("%d", &(head_nbr->nbr));
head_nbr->next = NULL;
}
return head_nbr;
}

void Displaynbr(Mynbr* first)
{
printf("\n===Function to display number===\n");
Mynbr* curr = first;
if (curr->next)
{
printf("The number is : %d", curr->nbr);
Displaynbr(first->next);
}
}

最佳答案

你离它并不远,但忘记了一条基本规则:当您更改函数中参数的值时,调用者的值保持不变

因此,AddNumber(几乎)正确返回列表头地址的新值,但choiceMenu立即丢弃它。

这里有一些修复:

AddNumber 应该能够将数字添加到空或非空列表中(注意:它当前导致 LIFO):

Mynbr* Addnumber(Mynbr* first){
printf("\n===Function to add a number===\n");
Mynbr* head_nbr = first;
head_nbr = (Mynbr*)malloc(sizeof(Mynbr));
printf("Enter a number :"); scanf("%d", &(head_nbr->nbr));
head_nbr->next = first; // just link to initial head, be it null or not

return head_nbr;
}

choiceMenu 不应丢弃新的头 - 您可以像对 AddNumber 那样将其返回给调用者,或者使用双重间接寻址:

void choiceMenu(int choice, Mynbr** first){
switch (choice){
case 1:
*first = Addnumber(*first);
break;

case 2:
break;
case 3:
break;
case 4:
Displaynbr(*first);
break;
case 5:
break;
}
}

(不要忘记更改初始声明并调用它:choiceMenu(choice, &head))

最后但并非最不重要的一点是,DisplayNumber 错误地测试了 curr->next 而不是 curr:

void Displaynbr(Mynbr* first){
printf("\n===Function to display number===\n");
Mynbr* curr = first;
if (curr) {
printf("The number is : %d", curr->nbr);
Displaynbr(first->next);
}
}

但这仍然显示===显示列表中每个值的数字===的函数。这里最好使用简单迭代而不是递归:

void Displaynbr(Mynbr* first){
printf("\n===Function to display number===\n");
Mynbr* curr = first;
while (curr) {
printf("The number is : %d\n", curr->nbr);
curr = curr->next;
}
}

或使用for循环:

void Displaynbr(Mynbr* first){
printf("\n===Function to display number===\n");
Mynbr* curr;
for (curr=first; curr != NULL; curr=curr->next) {
printf("The number is : %d\n", curr->nbr);
}
}

通过删除无用的局部变量,递归版本甚至可以更加简洁(感谢@sokkyoku 的提示):

void Displaynbr(Mynbr* first){
printf("\n===Function to display number===\n");
if (first) {
printf("The number is : %d", first->nbr);
Displaynbr(first->next);
}
}
<小时/>

如果您想更改AddNumber以拥有一个先进先出列表,您需要在列表末尾添加新元素。代码变为:

Mynbr* Addnumber(Mynbr* first){
printf("\n===Function to add a number===\n");
Mynbr* head_nbr = malloc(sizeof(Mynbr));
printf("Enter a number :"); scanf("%d", &(head_nbr->nbr));
head_nbr->next = NULL;
if (first == NULL) first = head_nbr;
else {
Mynbr* last = first;
while (last->next != NULL) last = last->next;
last->next = head_nbr;
}
return first;
}

但在这种情况下,保留指向列表最后一个元素的指针而不是浏览列表来查找它会更有效。

关于c - 我的函数不记住链表的头,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37700983/

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