跟踪与 C 中的局部变量同名的全局变量

Tracking global variables with the same name as local variables in C

当存在同名的局部变量时,我在跟踪全局变量的值时遇到了一些问题。

这是我正在使用的代码:

#include <stdio.h>

void func(int);

int x=6, y=7, z=10;

int
main(int argc, char **argv) {
    int z=5;
    printf("main: x=%2d, y=%2d, z=%2d\n", x, y, z);
    func(x);
    printf("main: x=%2d, y=%2d, z=%2d\n", x, y, z);
    func(y);
    printf("main: x=%2d, y=%2d, z=%2d\n", x, y, z);
    func(z);
    printf("main: x=%2d, y=%2d, z=%2d\n", x, y, z);
    return 0;
    }

void
func(int x) {
    x = x+1;
    y = y+1;
    printf("func: x=%2d, y=%2d, z=%2d\n", x, y, z);
}

请注意,除了 z 之外,全局变量与 func() 中的局部变量同名。当我运行程序。我得到以下输出:

main: x= 6, y= 7, z= 5
func: x= 7, y= 8, z=10
main: x= 6, y= 8, z= 5
func: x= 9, y= 9, z=10
main: x= 6, y= 9, z= 5
func: x= 6, y=10, z=10
main: x= 6, y=10, z= 5

我能理解第一行的出处。它只是全局变量的值,但 main 使用 5 而不是 10,因为全局变量隐藏了局部变量。我也能理解第2行。全局变量x被传递给func,得到一个7。全局变量y也被使用,得到一个8.

第 3 行是我忘记值的地方。为什么全局变量 y 的值保持为 8? func() 函数调用是否永久更改了它的值?我认为这是不可能的,因为 func() 中的 y 只是一个局部变量。不过,我知道 x = 6 来自第 3 行。

第4行我更迷路了。 x的值如何从6跳到9?

如果有人可以引导我完成此输出,并且可能给我一个关于范围和阴影的快速解释,那就太好了。

y 不是 func() 内的局部变量。为了让它成为一个局部变量(这会影响全局 [​​=11=] 变量),您必须在 func() 内声明另一个 y 变量,例如如下例所示。 (这个版本会一直打印"y=1",不会修改全局y变量。)

void
func(int x) {
    int y = 0;

    x = x+1;
    y = y+1;
    printf("func: x=%2d, y=%2d, z=%2d\n", x, y, z);
}

由于 y 不是原始 func() 中的局部变量,它正在递增全局 y.

请注意 x 也是 func() 的局部变量,并且按值传入。也就是说,调用 func(foo) 会将 foo 的值复制到 x 参数中,而更改 func() 中的 x 参数将 改变foo.

第 4 行来自 func(y) 调用。它会将 func() 内的(本地)x 参数设置为全局变量 y 的当前值。 y 恰好在该点具有值 8。 (它在之前调用 func() 时从 7 递增到 8。)func() 中的赋值 x = x+1 将其变为 9,然后打印出来。

回答你的第一个问题

Why has the value of global variable y stayed as 8? Did the func() function call change its value permanently?

是的,它确实永久地改变了全局变量 y,因为它是全局的而不是本地的(如果声明为 int y;,它就是本地的)

How can the value of x jump from 6 to 9?

您将全局变量 y 传递给函数,该变量在第一次函数调用中更改为 8。该值作为 x 在本地存储在函数中。所以 x + 1 将变成 9.

这就是全局变量的危险。一旦您将局部变量命名为相同的名称,您将忘记什么值包含什么值。

一个解释一些细节的小例子:

int x = 3;

int main(){
    int x = 8;
    printf("%d", x);
}

这将打印 8,因为代码将获取 x 的本地值。

此外,当您更改全局变量时,这将在程序的整个生命周期内被记住。