首页 > 解决方案 > 为什么要重新定义具有相同名称的结构,包含第一个结构的值,即使在第一个结构被销毁后声明第二个结构?

问题描述

#include <stdio.h>

typedef struct
{
    int a;
    int b;
}my_struct;

void check (my_struct *my_check)
{
    printf ("%d\n", my_check->a);
}

int main()
{
  //block with local variables
    {
    int a = 2;
    printf("int inside block %d\n", a);
    my_struct m1;
    m1.a = 2;
    printf ("my_struct m1 inside block\t");
    check (&m1);
    }
    
//outside the block; so the variables and their values inside the above block is outside the scope of the following code
    int a;
    printf("int outside block %d\n", a);
    my_struct m2;
    my_struct m1;
    printf ("my_struct m1 outside block\t");
    check (&m1);
    printf ("my_struct m2 outside block\t");
    check(&m2);
    
    return 0;
}

上面这段代码会输出

int inside block 2 
my_struct m1 inside block 2
int outside block 0
my_struct m1 outside block 2
my_struct m2 outside block 522062864

我的问题是:

  1. 为什么块内的“int a”不能用同名变量访问,即int a,但“my_struct m1”是?

我的理解是,如果它在块之外,那么它是新的声明和定义。外部变量需要新赋值,否则它们将包含默认/垃圾值

标签: cstructscope

解决方案


您处于未定义行为的世界中。您已经在内部块中创建了一些变量。美好的。然后,当您退出该块时,这些变量就会消失。您现在在外部创建不同的变量。并且您尝试使用那些显式未定义行为的未初始化变量。

这意味着发生的情况可能因一个系统而异,而另一个系统可能不同,或者在具有不同编译选项的同一系统上,甚至在不同的运行中发生。无论如何,你永远不应该依赖这种持续发生的事情。

现在在那个系统和那个特定的运行中实际发生了什么:你的实现可能使用堆栈来存储结构和寄存器来存储你从不使用地址的单个值。因此,当您创建一个新的单个变量时,它会接收寄存器中的内容,并且可以是任何内容。但是当你创建一个新结构时,它只是重用前一个结构刚刚释放的内存,你得到旧值。但正如我已经说过的,你不能依赖它。


推荐阅读