1
#include <stdio.h>
int inc1(int x)  { return x++;    }
int inc2(int *x) { return (*x)++; }

int
main(void)
{
    int a;
    a = 3;
    printf("%d\n", inc1(a) + a);
    printf("%d\n", inc2(a) + a);
    return 0;
}

私は過去の論文に取り組んでおり、質問の1つは、6行目と9行目の間に加えられた変更を追跡することです。このコード全体を通して、すばらしいでしょう。

4

2 に答える 2

3

あなたの投稿にエラーが含まれていない、このほぼ同一のコードについて説明します。

#include <stdio.h>

int inc1(int x)  { return x++;    }
int inc2(int *x) { return (*x)++; }

int main(void) {
    int a;
    a = 3;
    printf("%d\n", inc1(a) + a);
    printf("%d\n", inc2(&a) + a);
    return 0;
} 

aは 3 に初期化され、次にa の値が に渡されinc1()、それが返され、post-incrementを使用して 1 が追加されます。これは、返される実際の値がまだ 3 であることを意味します。

次に、a のアドレスが に渡されinc2()ます。つまり、x の値に起こることが a にも起こるということです。ここでもポストインクリメントが使用されているため、inc2()戻り値は 3 ですが、呼び出し後aは 4 です。

ただし、コンパイラは、 や などの式をシーケンス ポイント間の任意の順序で自由にa評価できinc2(&a)ます。これは、の右側にある が 3 または 4 のいずれかになる可能性があることを意味します (が の前または後に評価されるかによって、プログラムは6 7または6 6のいずれかを出力する可能性があります。ainc2(&a) + aaint2(&a)

于 2012-05-06T15:59:02.920 に答える
0

inc1()を呼び出す行は、「6」(3 + 3)を出力します[最初の3つはinc1()からのものであり、ポストインクリメント演算子のため、インクリメントされた値は返されません]。また、inc1()は値によって呼び出されるため、'a'の値は関数の外部では影響を受けません。

ここで、論文でinc2()を呼び出すステートメントが次のようになっている場合:

printf("%d\n", inc2(a) + a);

次に、コードはコンパイルされますが('a'にメモリ位置を格納することを期待して)、実行時にその値('a = 3'の場合)に応じて、逆参照しようとしているため、セグメンテーション違反が発生します。プログラムがアクセスすることを想定していないメモリ位置3。

または、ステートメントが次の場合:

printf("%d\n", inc2(&a) + a);

次に、inc2()はポインタ(アドレス)を介して「a」の値をインクリメントしますが、ポストインクリメント演算子を使用しているため、「a」(3)の古い値を返しますが、とにかく「a」とその後のアクセスをインクリメントします'a'に変更すると、新しい値が取得されます。次の「a」は、評価が左から右に行われるため、値「4」になります。したがって、7(3 + 4)が出力されます。

Cのポインタと変数の違いが明らかになることを願っています。

于 2012-05-11T16:51:56.007 に答える