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が何もしないことを確認できます。さらに、関数を終了するわずか1秒前の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

第 2 ラウンド:

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

単一のステップでgdb実際に何が起こるかがわかります。上記の行でstatic int xが変更されていることに注意してください。そのため、*a=x+10;実際には が変更されstatic int xます。したがって、最初の反復の後:

グローバルx=1 静的x=11

したがって、2 回目の反復では staticxが にインクリメントされ12、次に global にインクリメントされますx=1+12;。これによりグローバルになりx==13ます。コードの残りの部分は、グローバルxとグローバルに影響しなくなりaました。次にfoo、静的x変数に 10 を加算するだけで、グローバル変数とは関係ありません。

于 2013-02-19T11:12:56.383 に答える
0

Cは静的スコープを使用するため、同じ名前の変数が2つある場合、最初に現在のブロックで宣言された変数が使用され、次に外部ブロックが調べられます。したがって、staticintxはグローバル変数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
}

そして、これは2番目の呼び出しで起こることです:

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 に答える
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 に答える