【问题标题】:Tracking global variables with the same name as local variables in C在C中跟踪与局部变量同名的全局变量
【发布时间】:2015-03-23 23:17:17
【问题描述】:

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

这是我正在使用的代码:

#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);
}

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

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 只是一个局部变量。我明白第 3 行中 x = 6 的来源。

第 4 行我更加迷失了方向。 x的值怎么能从6跳到9?

如果有人能指导我完成这个输出,那将是非常棒的,也许能给我一个关于范围和阴影的快速解释。

【问题讨论】:

  • 您永远不会在 func 中声明 y,因此没有任何内容被隐藏。 func(x) in main 也不会影响全局 x
  • 如果你真的想不明白,在main() 中声明int z = 5; 之前添加printf("main: x=%2d, y=%2d, z=%2d\n", x, y, z);(假设C99 或更高版本支持),并添加:{ int z = 20; printf("main: x=%2d, y=%2d, z=%2d\n", x, y, z); },在其中之一之后其他printf() 电话。

标签: c scope global-variables


【解决方案1】:

回答你的第一个问题

为什么全局变量 y 的值一直是 8? func() 函数调用是否永久改变了它的值?

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

x的值怎么能从6跳到9?

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

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

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

int x = 3;

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

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

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

【讨论】:

    【解决方案2】:

    y 不是func() 中的局部变量。为了使它成为一个局部变量(它会影响全局变量y),你必须在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。 p>

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

    【讨论】:

      猜你喜欢
      • 2016-04-06
      • 1970-01-01
      • 1970-01-01
      • 2014-04-24
      • 1970-01-01
      • 2011-08-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多