简体   繁体   English

简单C程序的奇怪输出

[英]Weird output on a simple C program

I have the following come in C: 我有以下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;
}

I can clearly debug it and see that the line *a += x doesn't do anything plus I can see that the value of x just a second before going out of the function is 22 and it prints out 13 . 我可以清楚地对其进行调试,并看到*a += x不执行任何操作,而且我可以看到,离开该函数前一秒的x值为22 ,并打印出13

When I did it in my head, I've go 34, which should be the right answer as far as I can see. 当我脑海中动起来时,我已经走了34岁,就我所见,这应该是正确的答案。 Can somebody explain where I might be wrong? 有人可以解释我可能在哪里错吗?

Let's do it step by step. 让我们一步一步地做。

First round: 第一回合:

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

Second round: 第二轮:

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

It's easy. 这很容易。 The tricky part is to recognize the different copies of x , and the scope of a inside the function. 棘手的部分是认识的不同副本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;
 }

Single stepping it in a gdb should tell you what actually happens. 将其单步进入gdb应该可以告诉您实际发生了什么。 Just notice that on the line marked above, the static int x is changed. 请注意,在上面标记的行上, static int x已更改。 so the *a=x+10; 所以*a=x+10; actually changes the static int x . 实际上更改了static int x So after the first iteration: 因此,在第一次迭代之后:

Global x =1 static x =11 全局x = 1静态x = 11

So in the second iteration static x is incremented to 12 , then global x=1+12; 因此,在第二次迭代中,静态x增加到12 ,然后全局x=1+12; . this makes global x==13 . 这使得全局x==13 The rest of the code doesn't affect global x and global a anymore. 其余代码不再影响global x和global a The foo then simply adds the static x by 10, which is irrelevant to the global variable. foo然后简单地将静态x加10,这与全局变量无关。

This makes it easier to see 这样更容易看清

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

Since C uses static scope, when there are two variables with the same name, it will be used first the one declared in the current block, then it will look at external blocks. 因为C使用静态作用域,所以当有两个同名变量时,将首先使用在当前块中声明的变量,然后再查看外部块。 So static int x shadows the global variable x. 因此,静态int x遮盖了全局变量x。 Also another thing that you should note is that in C arguments are passed by value, so if you assign a copy of the value you don't affect the original value. 您还应该注意的另一件事是,C语言中的参数是按值传递的,因此,如果您分配值的副本,则不会影响原始值。

Let's imagine a case where the global variable x has address 0x8000 , and the static variable x is at address 0x9000. 让我们想象一下全局变量x的地址为0x8000,而静态变量x的地址为0x9000的情况。 This is what happens at the first call: 这是第一次调用时发生的情况:

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
}

And this is what happens in the second call: 这就是第二个调用中发生的情况:

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
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM