C-堆栈分配链表
下面代码的目标是让用户输入一些整数,将这些整数存储在C-堆栈分配链表,c,linked-list,C,Linked List,下面代码的目标是让用户输入一些整数,将这些整数存储在INT\u NODE类型的堆栈分配节点中,然后将所有这些节点链接在一起。最后,我希望遍历列表并在每个节点上打印出元素(仅在下面代码中的前5个)。然而,当我输入一些数字时,程序会打印出我输入的第一个数字,然后我输入的最后一个数字会重复4次。例如,如果我输入84 5 12 7 1 22 31[enter],然后在下一行的开头按Ctrl+D,在这个Mac上模拟EOF,我会得到以下输出:84 31。我不明白它为什么这样做 我知道我可以使用malloc(
INT\u NODE
类型的堆栈分配节点中,然后将所有这些节点链接在一起。最后,我希望遍历列表并在每个节点上打印出元素(仅在下面代码中的前5个)。然而,当我输入一些数字时,程序会打印出我输入的第一个数字,然后我输入的最后一个数字会重复4次。例如,如果我输入84 5 12 7 1 22 31[enter]
,然后在下一行的开头按Ctrl+D
,在这个Mac上模拟EOF,我会得到以下输出:<代码>84 31。我不明白它为什么这样做
我知道我可以使用malloc()
在堆上分配节点,我已经编写了一个函数来实现这一点。我只是想知道是否可以使用运行时堆栈来完成它
在下面的代码中,INT\u节点
类型在“SortingAlgs.h”
标题中定义如下:
typedef struct INT_NODE {
int element;
struct INT_NODE *next;
} INT_NODE;
#包括
#包括
#包括“SortingAlgs.h”
内部主(空){
INT_节点头={-9999999};
int-num;
INT_NODE*pccurrentnode=&head;
如果(扫描频率(“%d”,&num)!=EOF){
head.element=num;
while(scanf(“%d”,&num)!=EOF){
INT_NODE newNode;
newNode.element=num;
newNode.next=NULL;
pCurrentNode->next=&newNode;
PCcurrentNode=PCcurrentNode->next;
}
}
int i;
对于(pccurrentnode=&head,i=0;i<5;
pCurrentNode=pCurrentNode->next,i++)
printf(“%d”,pCurrentNode->element);
printf(“\n”);
返回0;
}
要使用运行时堆栈执行此操作,可以使用以下选项之一:
alloca
分配运行时。这很简单:基本上只需将malloc
替换为alloca
(不要试图将alloca
包装到另一个函数中)。但是,alloca
不是标准函数INT\u NODE
对象。实际上,您通常会一次又一次地重用同一内存位置,从而有效地将单个节点链接到自身
下面是一个例子,如果一个实现按照递归方法将整个列表保持在“堆栈上”。当然,只有当所有递归调用都处于“活动”状态时,列表才会存在。这限制了这项技术的适用性,但也有它的用途
#include <stdlib.h>
#include <stdio.h>
typedef struct INT_NODE
{
int element;
struct INT_NODE *next;
} INT_NODE;
void print_list(const INT_NODE *head)
{
for (const INT_NODE *current = head; current != NULL; current = current->next)
printf("%d ", current->element);
printf("\n");
}
void build_list(INT_NODE *head, INT_NODE *last)
{
INT_NODE new = { 0 };
if (scanf("%d", &new.element) != 1)
{
print_list(head);
return;
}
if (head == NULL)
head = &new;
else
last->next = &new;
build_list(head, &new);
}
int main(void)
{
build_list(NULL, NULL);
}
#包括
#包括
类型定义结构内部节点
{
int元素;
结构INT_节点*下一步;
}INT_节点;
无效打印列表(常量内部节点*头)
{
for(常数INT_节点*当前=头部;当前!=NULL;当前=当前->下一步)
printf(“%d”,当前->元素);
printf(“\n”);
}
无效生成列表(内部节点*头部,内部节点*最后)
{
INT_NODE new={0};
if(scanf(“%d”,&new.element)!=1)
{
打印列表(标题);
返回;
}
if(head==NULL)
head=&new;
其他的
最后->下一步=&new;
构建列表(标题和新建);
}
内部主(空)
{
构建列表(空,空);
}
我认为原因在于变量的范围。 输入5,程序在堆栈上分配内存,但它将被返回。 输入12,分配相同的内存,然后返回。 最后,头下一个指针是同一个内存,下一个指针是同一个内存本身
您可以输出5个以上。也许你会得到8431 谁将为此分配足够的内存?要使用运行时堆栈进行分配,您需要1)通过
alloca
进行非标准运行时分配,或者2)递归函数,其中每一级递归将承载一个列表节点。就这样。你现在所拥有的是不可行的,只会导致未定义的行为。当然,您可以简单地预先分配固定数量的节点作为本地数组,并希望它足以满足您的列表。。。但我相信这不是你的意思代码>:这在范围外无效。每次while循环中,您都在创建和销毁yr节点。必须在heapNote上执行此操作,您的打印循环停止的唯一原因是因为i<5
术语。对于一个真正的链表,您将一直运行,直到到达一个下一个指针为空的节点(最常见的情况)。如果你试着这样做,你很可能会得到“永远”产生的31
(直到你感到无聊并杀死你的程序)。这是你麻烦的征兆。请在确定的情况下发布答案。哦,不,我要打绿色复选标记的答案不见了(
#include <stdlib.h>
#include <stdio.h>
typedef struct INT_NODE
{
int element;
struct INT_NODE *next;
} INT_NODE;
void print_list(const INT_NODE *head)
{
for (const INT_NODE *current = head; current != NULL; current = current->next)
printf("%d ", current->element);
printf("\n");
}
void build_list(INT_NODE *head, INT_NODE *last)
{
INT_NODE new = { 0 };
if (scanf("%d", &new.element) != 1)
{
print_list(head);
return;
}
if (head == NULL)
head = &new;
else
last->next = &new;
build_list(head, &new);
}
int main(void)
{
build_list(NULL, NULL);
}