循环中的变量范围

The*_*ian 6 c variables scope

这可能是我遇到的最奇怪的事情之一.我不用C语言编程,但从我所知道的是真实加上在线检查不同来源,变量macroNamemacroBody只在while循环的范围内定义.因此,每次循环运行时,我都期望marcoNamemacroBody获取新地址并成为全新的变量.然而,事实并非如此.

我发现即使循环再次运行,两个变量共享相同的地址,这使我严重头疼链接列表,我需要检查元素的唯一性.我不知道为什么会这样.每次while循环运行时,macroNamemacroBody都不应该获得全新的地址吗?

我知道这是问题所在,因为我打印地址并且它们是相同的.

while(fgets(line, sizeof(line), fp) != NULL) // Get new line
{
    char macroName[MAXLINE];
    char macroBody[MAXLINE];

    // ... more code

    switch (command_type)
    {
        case hake_macro_definition:
            // ... more code

            printf("**********%p | %p\n", &macroName, &macroBody);
            break;

        // .... more cases
    }
}
Run Code Online (Sandbox Code Playgroud)

代码是我的链表代码的一部分.

struct macro {
    struct macro *next;
    struct macro *previous;
    char *name;
    char *body;
};    
Run Code Online (Sandbox Code Playgroud)

检查元素是否已存在于链表中的函数.但由于*name具有相同的地址,我总是在if条件内.

static struct macro *macro_lookup(char *name)
{
    struct macro *temp = macro_list_head;

    while (temp != NULL)
    {
        if (are_strings_equal(name, temp->name))
        {
            break;
        }    

        temp = temp->next;
    }

    return temp;
}
Run Code Online (Sandbox Code Playgroud)

chr*_*ock 5

这些数组在堆栈上分配:

char macroName[MAXLINE];
char macroBody[MAXLINE];
Run Code Online (Sandbox Code Playgroud)

编译器为您在函数的开头存在预先分配的空间.换句话说,从计算机的角度来看,这些数组的位置与在函数体顶部的循环体外定义它们的位置相同.

C中的范围仅表示标识符可见的位置.因此编译器(但不是计算机)强制执行语义,macroName并且macroBody不能在循环体之前或之后引用.但是从计算机的角度来看,一旦函数启动,这些数组的实际数据就会存在,并且只有在函数结束时才会消失.

如果你要查看代码的汇编转储,你可能会看到你的机器的帧指针递减了足够大的量,以便函数的调用堆栈为所有局部变量(包括这些数组)留出空间.

  • @ThePedestrian这样的东西.您可以通过动态内存分配获得"新"空间,即通过`malloc()`.顺便说一下,如果你有兴趣了解这些东西是如何工作的,那么整个研究领域就被称为*计算机组织*. (2认同)