-1

私は自分の問題を表現する方法がわかりません。aコードは以下のとおりです。値が変更された理由を教えてください。私の意見では、は...のアドレスではGET macroなく、 の値を返すだけです。aa

#include <stdio.h>

#define GET(addr) (*(int *)(&addr))

int main()
{
    int a = 10;
    GET(a) = 20;
    printf("%d\n", a);
}
4

4 に答える 4

3

マクロを展開すると、次のようになります。

(*(int *)(&a)) = 20

を忘れる(int *)と、

(*(&a)) = 20

これは次のようになります:

a = 20;

aしたがって、 !の値を変更しています。

于 2012-12-16T11:47:09.040 に答える
1

ポインターを逆参照した結果はL-valueです。これは、アドレスがあるためです。それは確かに割り当てることができます。

より簡単な例を考えてみましょう:が配列またはポインターの場合、次のように にp確実に割り当てることができますp[0]

p[0] = 20;

p[0]と同じであることを思い出して*pください。マクロを展開します。

*((int*)&a) = 20;

これは、

(&a)[0] = 20;

これは確かに有効な (やや非正統的ではありますが)a自体の割り当てです。

于 2012-12-16T11:50:09.683 に答える
1

GET(a) = 20行は次のように展開されます。

(*(int *)(&a)) = 20;

冗長なキャストと外側の括弧を取り除きましょう:

*(&a) = 20;

aこれは、次と同等であるため、明らかにへの割り当てです。

a = 20;

目的が左辺値としての誤った使用を防ぐことである場合はGET()、次のように変更できます。

#define GET(addr) ((int)addr)

これにより、コードをコンパイルしようとすると失敗します

test.c:8:12: error: lvalue required as left operand of assignment
于 2012-12-16T11:46:47.697 に答える
1

あなたが持っていたとしましょう:

int *b = ...;
*b = 10;

上記は、b指し示す整数に 10 を割り当てます。

あなたのマクロは、 (およびノー​​オペレーションキャスト)にb置き換えられて、ほとんど同じことを行います。&a

于 2012-12-16T11:47:31.293 に答える