Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C中的单链表输出不正确_C_Linked List_Output - Fatal编程技术网

C中的单链表输出不正确

C中的单链表输出不正确,c,linked-list,output,C,Linked List,Output,所以我正在做一些链表修改,我试着加载一个带有数字的列表,然后打印出来。下面是我的代码: #include <stdio.h> #include <stdlib.h> typedef struct stack { int data; struct stack *next; }*stack; stack create_s(void){ stack s = (void*)malloc(sizeof(stack)); s->next = NULL

所以我正在做一些链表修改,我试着加载一个带有数字的列表,然后打印出来。下面是我的代码:

#include <stdio.h>
#include <stdlib.h>

typedef struct stack {
   int data;
   struct stack *next;
}*stack;

stack create_s(void){
   stack s = (void*)malloc(sizeof(stack));
   s->next = NULL;

   return s;
}

void push_s(stack s, int data) {
   while (s->next != NULL) {
      s = s->next;
      }

   s->next = (void*)malloc(sizeof(stack));
   s=s->next;
   s->data = data;
   s->next = NULL;
}

void print_s(stack s) {
   if (s==NULL) {
      return;
   } 
   else {
      while (s->next != NULL) {
         printf("%d\n",s->data);
         s=s->next;
      }
   }
}

int main (void) {
   stack s = create_s();

   push_s(s,2);
   push_s(s,4);
   push_s(s,6);
   push_s(s,8);

   print_s(s);

   return 0;
}
应该是什么时候

2
4
6
8
它是否在开始时打印我的结构的地址?还有,为什么它不打印我的最后一个元素


谢谢

代码包含几个错误,但首先引人注目的是,您的内存分配显然已经中断

stack s = (void*)malloc(sizeof(stack));
您将
stack
定义为指针类型。这意味着
sizeof(stack)
的计算结果为指针大小,而上面的
malloc
分配了足够的空间来存储单个指针,而不足以存储整个
struct stack
对象。
push\s
中也存在相同的内存分配错误

这里有一些建议

  • 不要在typedef名称后面隐藏指针类型。将您的
    堆栈定义为

    typedef struct stack{
      int data;
      struct stack *next;
    } stack;
    
    并在需要指针的地方使用
    stack*
    。也就是说,使
    *
    可见,而不是将其“隐藏”在typedef名称中。这将使您的代码更易于阅读

  • 不要强制转换
    malloc
    的结果。无论如何,当它已经是
    void*
    时,将它强制转换为
    void*
    有什么意义呢

  • 不要在类型中使用
    sizeof
    ,除非你真的必须这样做。喜欢将
    sizeof
    与表达式一起使用。学习使用下列
    malloc
    习惯用法

    T *p = malloc(sizeof *p);
    
    或者,在你的情况下

    struct stack *s = malloc(sizeof *s);
    
    这将分配适当大小的内存块

  • 此外,正如@WhozCraig在评论中所指出的,列表中的第一个节点显然应该作为“哨兵”头节点(具有未定义的
    数据
    值)。在代码中,您从未初始化该头部节点中的
    数据
    值。然而,在
    print_s
    函数中,您试图从head节点打印
    数据
    值。难怪您将垃圾(
    -1853045587
    )作为输出的第一行。不要打印第一个节点。跳过它,如果它真的是一个哨兵

    此外,
    print_s
    中的循环终止条件看起来很奇怪

    while (s->next != NULL)
    

    为什么要检查
    s->next
    中的
    NULL
    而不是检查
    s
    本身?此条件将提前终止循环,而不会尝试打印列表中最后一个节点。这就是为什么在输出中看不到最后一个元素(
    8
    )的原因。

    代码包含几个错误,但首先引人注目的是,内存分配显然已经中断

    stack s = (void*)malloc(sizeof(stack));
    
    您将
    stack
    定义为指针类型。这意味着
    sizeof(stack)
    的计算结果为指针大小,而上面的
    malloc
    分配了足够的空间来存储单个指针,而不足以存储整个
    struct stack
    对象。
    push\s
    中也存在相同的内存分配错误

    这里有一些建议

  • 不要在typedef名称后面隐藏指针类型。将您的
    堆栈定义为

    typedef struct stack{
      int data;
      struct stack *next;
    } stack;
    
    并在需要指针的地方使用
    stack*
    。也就是说,使
    *
    可见,而不是将其“隐藏”在typedef名称中。这将使您的代码更易于阅读

  • 不要强制转换
    malloc
    的结果。无论如何,当它已经是
    void*
    时,将它强制转换为
    void*
    有什么意义呢

  • 不要在类型中使用
    sizeof
    ,除非你真的必须这样做。喜欢将
    sizeof
    与表达式一起使用。学习使用下列
    malloc
    习惯用法

    T *p = malloc(sizeof *p);
    
    或者,在你的情况下

    struct stack *s = malloc(sizeof *s);
    
    这将分配适当大小的内存块

  • 此外,正如@WhozCraig在评论中所指出的,列表中的第一个节点显然应该作为“哨兵”头节点(具有未定义的
    数据
    值)。在代码中,您从未初始化该头部节点中的
    数据
    值。然而,在
    print_s
    函数中,您试图从head节点打印
    数据
    值。难怪您将垃圾(
    -1853045587
    )作为输出的第一行。不要打印第一个节点。跳过它,如果它真的是一个哨兵

    此外,
    print_s
    中的循环终止条件看起来很奇怪

    while (s->next != NULL)
    

    为什么要检查
    s->next
    中的
    NULL
    而不是检查
    s
    本身?此条件将提前终止循环,而不会尝试打印列表中最后一个节点。这就是您在输出中看不到最后一个元素(
    8
    )的原因。

    可以通过更改以下内容来修复给定输出的实际原因:

    s=s->next;
    s->data = data;
    


    给定输出的实际原因可以通过更改以下内容来修复:

    s=s->next;
    s->data = data;
    


    我很好奇为什么将节点命名为堆栈!:我很好奇为什么要将节点命名为堆栈!:pOne另一个问题:
    create_s
    使用未初始化的
    data
    成员创建节点。@WhozCraig:是的,你是对的。我没有立即意识到,
    push_s
    会迭代到列表的末尾。我有点“假设”它增加了列表的开头。不知道这个答案的否决票是从哪里来的,这里的一切都是明确正确的(+1,顺便说一句)@user3558437是一个传统的实现。如果你不知道,这不是一堆。如果有什么事的话,那就是排队。谢谢你们的帮助。我对这一切都不熟悉,只是在尝试。我采纳了你的建议。另一个问题是:
    create\u s
    使用未初始化的
    data
    成员创建节点。@WhozCraig:是的,你是对的。我没有立即意识到,
    push_s
    会迭代到列表的末尾。我有点“假设”它增加了列表的开头。对这个答案的否决票来自何方也没有任何线索。这里的一切都很清楚