c - C 问题,程序打印不应该打印的值

标签 c

几天来我一直在尝试查找此代码的问题,但我仍然找不到。这里的主要问题是,当打印每个节点的值时,它会尝试打印一个额外的节点并组成新值。

代码按以下方式工作,例如:我输入数字 10、11、15,如果节点的所有三个数字的总和大于 20,那么它会在前面加上 double ,所以结果将是:20, 22,30 || 10,11,15。

每次我尝试在 Visual Studio Code 中执行此代码时,程序都会打印: 20,22,30 || 10,11,15 || 0,26345856,301989906。如您所见,该程序试图打印另一个不存在的节点,以便它构成值。我试过一些在线编译器,这不是问题,所以我想知道我的代码是否有任何错误,或者是否是编译器的问题。

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

typedef struct list{
    int num;
    int num1;
    int num3;
    struct list *next;
}node;


void create (node *p){
    printf("Input first number: ");
    scanf("%d",&p->num);
    if (p->num==0)
        p->next=NULL;
    else{
        printf("Input second number: ");
        scanf("%d",&p->num1);
        printf("Input third number: ");
        scanf("%d",&p->num3);
        p->next=(node*)malloc(sizeof(node));
        create (p->next);
    }
}

void show (node *p){
    if (p->next !=NULL){
        printf ("\n%d",p->num);
        printf ("\n%d",p->num1);
        printf ("\n%d",p->num3);
        show (p->next);
    }
}

node* add(node *p){
    node *aux;
    if((p->num+p->num1+p->num3)>20){
        aux=(node *)malloc(sizeof(node));
        aux->num=p->num*2;
        aux->num1=p->num1*2;
        aux->num3=p->num3*2;
        aux->next=p;
        p=aux;
    }
    return p;
}

void add2 (node *p){
    node *aux=NULL;
    while(p->next!=NULL){
        if((p->next->num +p->next->num1+ p->next->num3)>20){
            aux=(node *)malloc(sizeof(node));
            aux->num=p->next->num*2;  
            aux->num1=p->next->num1*2;
            aux->num3=p->next->num3*2;
            aux->next=p->next; 
            p->next=aux;
            p=p->next;
        }
        p=p->next;
    }
}

int main(){
    node *prin=NULL;
    prin=(node*)malloc(sizeof(node));
    create(prin);
    printf("Input numbers were: ");
    show (prin);
    prin=add(prin);
    add2(prin->next); 
    printf("\nList with added nodes: ");
    show(prin);
}

最佳答案

总是在列表底部创建一个“虚拟”节点。例如,如果您输入 0 作为第一个输入,您将得到一个单条目列表,其中只有 num(设置为 0) 和 next(设置为 NULL)成员被初始化。 num1num3 字段未被 create 函数初始化。同样,如果您在给定的测试用例中为最后两个字段输入(并初始化)实际值,您将仍然在下一次调用 时创建一个新的“foot”节点创建

碰巧,在您的系统上,这些未初始化的数据字段具有“随机”值,这些值加在一起超过 20。(这是 C 标准完全允许的,但某些编译器和/或平台会,默认情况下,将未初始化的数据设置为零。)

因此,在调用 add 函数时,if 测试条件:

    if ((p->num + p->num1 + p->num3) > 20) {
        //...

将评估为 TRUE 并添加一个新节点,其中 num1num3 的值是原始“随机”的两倍值(value)观。

要解决此问题,请在 create 函数中将 num1num3 字段设置为零(或其他一些小/负数) ,当为 num 字段输入“sentinel zero”输入结束标记时:

void create(node* p)
{
    printf("Input first number: ");
    scanf("%d", &p->num);
    if (p->num == 0) {
        p->next = NULL;
        p->num1 = 0; // You MUST ensure that the sum of these two numbers
        p->num3 = 0; // is LESS THAN 20 ... or a new node will be created
    }
    else {
        printf("Input second number: ");
        scanf("%d", &p->num1);
        printf("Input third number: ");
        scanf("%d", &p->num3);
        p->next = (node*)malloc(sizeof(node));
        create(p->next);
    }
}

编辑:要查看此“错误”是如何发生的,请尝试将 num1 字段设置为特定数字(例如 42)并保留 num3 未初始化。然后,只有一个“虚构”值无法解释 - 另一个将是您指定值的两倍(因此,84)。这将是一个很好的练习,恕我直言。

关于c - C 问题,程序打印不应该打印的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64344421/

相关文章:

c - SQL 中的外部 C 函数

c - linux 是否允许从信号处理程序进行任何系统调用?

c - Glade 和静态链接

C --> header 和变量

c - 将数据存储在自定义索引: GWLP_USERDATA_EX?中

c - 读取行中的字并将字存储在 3D 数组中

将 1 字节数字转换为十进制

c++ - C/C++ 库的想法

C 使用按位运算符判断二进制数是否将所有偶数设置为 0

C - 错误冲突类型。定义了函数原型(prototype)