显示最后一个负元素的 C 编程列表节点

C programming list node showing last negative element

我在使用链表时遇到了一些问题。所以基本上用户只会继续输入值,这些值将被添加到链表中,直到用户输入 -1。这是我的代码:

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

typedef struct node
{
    int num;
    struct node *next;
}ListNode;

int main() {
    int n = 0;
    ListNode *newNode = NULL, *head = NULL;
    newNode = malloc(sizeof(ListNode));
    head = newNode;

    printf("Enter a list of numbers, terminated by the value -1: ");
    do {
        scanf("%d", &n);
        if (n == -1) {
            newNode->next = NULL;
            break;
        }
        else {
            newNode->num = n;
            newNode->next = malloc(sizeof(ListNode));
            newNode = newNode->next;
        }
    } while (n != -1);

    newNode = head;
    while (newNode != NULL)
    {
        printf("%d ", newNode->num);
        newNode = newNode->next;
    }

    return 0;
}

假设我输入了 1 2 3 4 -1。预期输出应该是 1 2 3 4。但是,我得到 1 2 3 4 -842150451。我想知道为什么会有 -ve 号。问题出在我的打印 listNode 部分吗?

提前致谢。

do/while 循环中分配的下一个节点未初始化。因此,最后一个节点有一个未确定的 num 字段。

不要使用 do/while 循环。检查scanf的return值,根据需要分配节点,而不是提前分配。

这是更正和简化的版本:

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

typedef struct node {
    int num;
    struct node *next;
} ListNode;

int main(void) {
    int n;
    ListNode *head = NULL, **tailp = &head;

    printf("Enter a list of numbers, terminated by the value -1: ");
    while (scanf("%d", &n) == 1 && n != -1) {
        ListNode *newNode = malloc(sizeof(ListNode));
        newNode->num = n;
        newNode->next = NULL;
        *tailp = newNode;
        tailp = &newNode->next;
    }

    for (ListNode *np = head; np != NULL; np = np->next) {
        printf("%d ", np->num);
    }
    printf("\n");

    return 0;
}

你总是比用户输入的数字多分配一个节点。最后一个节点的 num 未初始化(这是您的垃圾值的来源)。

这是一个可能的解决方法:

ListNode **pnode, *head = NULL;
pnode = &head;

printf("Enter a list of numbers, terminated by the value -1: ");
while (scanf("%d", &n) == 1 && n != -1) {
    *pnode = malloc(sizeof **pnode);
    (*pnode)->num = n;
    (*pnode)->next = NULL;
    pnode = &(*pnode)->next;
}

循环条件确保我们能够读取一个数字,并且该数字不是 -1。

之后我们只分配一个新节点(即我们只分配与输入的数字一样多的节点)。

pnode 指向节点链中的最后一个指针。它标记了应该插入下一个节点的位置。最初这是 &head(即第一个节点存储在 head 中(通过分配给 *pnode)),但它随着每次插入(pnode = &(*pnode)->next、新的最后一个指针)。

您可以将打印循环更改为:

while (newNode->next != NULL)
    {
        printf("%d ", newNode->num);
        newNode = newNode->next;
    }

尽管这不会打印您正在创建的最后一个冗余节点。如果你修改你的代码,那么你首先没有冗余节点会更好!

每当您通过执行 newNode->num = nelse 块内的节点添加值时,在您通过执行 newNode->next=malloc(sizeof(ListNode)) 创建新节点后不久。想想如果它是您刚刚插入的列表中的最后一个值会怎样。之后真的需要创建一个新节点吗?

列表中的节点总是比您的值多一个。最后一个节点的 num 值未分配。如果第一个值为 -1 会怎样? head 中应该还有一个节点。删除第一个 malloc,并在循环内,在 malloc 之后分配 newNode->num。您必须在那里分配 head,方法是检查它是否仍然为空。

根据 newNode->next != NULL 条件打印时使用 'while' 循环应该可以解决您的问题。