了解古代C

时间:2019-10-01 17:01:34

标签: c turbo-c++

如果您不熟悉动态内存分配,则可以将其视为大脑绞痛。

首先将此代码另存为bin程序中的C程序。

#include<stdio.h>
#include<conio.h>

struct node {
   int data;
   struct node *next;
} *head=NULL;

void ins_at_beg()
{
    struct node *node=malloc(4);
    node->next=head; head=node;
    printf("Please enter the value to be inserted at the start: ");
    scanf("%d",node); // POINT A
}

void ins_at_end()
{
    struct node *node=head;
    while(node->next) node=node->next;
    node->next=malloc(4);
    printf("Please enter the value to be inserted at the end: ");
    scanf("%d",node->next->data); // POINT B
}

void main()
{
    clrscr();
    ins_at_end();
    printf("%d",head->data);
    getch();
}

执行此代码,一切都会正常。

现在,在程序将主要功能的ins_at_end()执行到ins_at_beg()并执行了程序之后,一切仍然看起来很好。

现在手动撤消上述更改(将ins_at_beg更改为ins_at_end)并执行程序。现在,您将获得head->data的值为0。

现在,只需将“ Point A”的node更改为node->data,您将看到输入的值会反映在屏幕上(注意:我们没有在主要功能)

现在再次反转上述更改,并将0作为默认值head->data

这里要注意的主要事情是,输出会被刚刚定义的函数更改,而该函数在主函数中未调用。

玩一会儿,您就会知道我在说什么。

问题:,即使我实际上没有调用在主函数中进行更改的函数,将node更改为node->data时,程序为何仍能正常工作功能?

1 个答案:

答案 0 :(得分:2)

此:

scanf("%d",node);

这:

scanf("%d",node->next->data);

不正确。 %d格式说明符期望int *作为参数。但是,在一种情况下,您传递的是struct node *,在另一种情况下,您传递的是int。对scanf使用错误的格式说明符会调用undefined behavior,这就是为什么您看到奇怪结果的原因。

您应该这样做:

scanf("%d",&node->data);

这:

scanf("%d",&node->next->data);

此外,这还假设了指针的大小:

struct node *node=malloc(4);

您应该这样做:

struct node *node=malloc(sizeof(*node));

您在这里也遇到了问题:

void ins_at_end()
{
    struct node *node=head;
    while(node->next) node=node->next;  //   <--- here
    node->next=malloc(4);
    printf("Please enter the value to be inserted at the end: ");
    scanf("%d",node->next->data); // POINT B
}

在程序启动时,head为NULL,因此您试图取消引用NULL指针,这再次导致未定义的行为。在执行其他任何操作之前,请检查这种情况。另外,您应将列表末尾的next指针显式设置为NULL。

void ins_at_end()
{
    struct node *node=malloc(sizeof(*node));
    struct node *tmp;

    printf("Please enter the value to be inserted at the end: ");
    scanf("%d",&node->data);
    node->next = NULL;

    if (!head) {
        head = node;
    } else {
        tmp = head;
        while (tmp->next) tmp = tmp->next;
        tmp->next = node;
    }
}