0

我在 C 中有以下内容:

int x = 0;
int *a = &x;

void foo(int *a)
{
    static int x = 0;
    x++;
    *a += x;
    a = &x;
    *a = x + 10;
}

int _tmain(int argc, _TCHAR* argv[])
{
    foo(a);
    foo(a);
    printf("%d\n", *a);

    return 0;
}

我可以清楚地调试它并看到该行*a += x没有做任何事情,而且我可以看到 x 的值在退出函数前一秒钟是22并且它打印出来13

当我在脑海中这样做时,我已经选择了 34,据我所知,这应该是正确的答案。有人可以解释我可能错在哪里吗?

4

4 回答 4

7

让我们一步一步来。

第一回合:

int x = 0; // global "x"

static int x = 0; // local "x" = 0
x++; // local "x" = 1
*a += x; // global "x" += local "x" results in global "x" = 1
a = &x; // local "a" points to local "x"
*a = x + 10; // local "x" = local "x" + 10 results in local "x" = 11

第二轮:

int x = 0; // global "x" = 1 now

static int x = 0; // local "x" = 11 now
x++; // local "x" = 12
*a += x; // global "x" += local "x" results in global "x" = 13
a = &x; // local "a" points to local "x"
*a = x + 10; // local "x" = local "x" + 10 results in local "x" = 22

printf("%d\n", *a); // prints global "x", 13
于 2013-02-19T11:14:55.617 回答
2

这简单。棘手的部分是识别 的不同副本,以及函数内部的x范围。a

void foo(int *a)
{
    static int x = 0;
    x++;
    *a += x;
     a = &x;   //<==== this doesn't change the a outside you see, a now points to static x
    *a = x + 10;
 }

单步执行 agdb应该会告诉您实际发生的情况。请注意,在上面标记的行上,static int x已更改。所以*a=x+10;实际上改变了static int x. 所以在第一次迭代之后:

全局x=1 静态x=11

所以在第二次迭代中 staticx递增到12,然后 global x=1+12;。这使得全局x==13. 其余代码不再影响全局x和全局a。然后foo简单地将静态x加 10,这与全局变量无关。

于 2013-02-19T11:12:56.383 回答
0

这样更容易看到

int x = 0;
int *a = &x;

void foo(int *a)
{
    static int y = 0;
    y++;
    *a += y;

      a = &y;        // a doesn't point to x anymore!!!
    *a = y + 10;
}
int _tmain(int argc, _TCHAR* argv[])
{
    foo(a);
    foo(a); // Now 'a' again points to the global 'x' (once more) 
    printf("%d\n", *a);

    return 0;
}
于 2013-02-19T11:13:31.557 回答
0

由于 C 使用静态作用域,当有两个同名变量时,它会先使用当前块中声明的那个,然后再查看外部块。所以 static int x 会影响全局变量 x。您还应该注意的另一件事是,在 C 中,参数是按值传递的,因此如果您分配值的副本,则不会影响原始值。

假设全局变量 x 的地址为 0x8000,静态变量 x 的地址为 0x9000。这是第一次调用时发生的情况:

void foo(int *a)  // a= 0x8000 , global int x=0
{
    static int x = 0;
    x++;         // static int x=1
    *a += x;     // global int x=1
    a = &x;      // a=0x9000 (only a copy of a is assigned, so the global a will remain 0x8000)
    *a = x + 10;     // static int x= 11
}

这就是第二次调用中发生的情况:

void foo(int *a)  // a= 0x8000 , global int x=1, static int x=11
{
    static int x = 0;
    x++;         // static int x=12
    *a += x;     // global int x= 13
    a = &x;      // a=0x9000
    *a = x + 10;     // static int x= 22
}
于 2013-02-19T11:31:17.533 回答