3

^= を使用して値を交換しようとしましたが (これを行うには別の変数を使用する方がよいことはわかっています)、結果は正しくありません。

#include <stdio.h>

int main() {
    int a = 3, b = 5, *pa = &a, **ppa = &pa, *pb = &b, **ppb = &pb;
    *pa ^= *pb;
    *pb ^= *pa;
    *pa ^= *pb;
    printf("pointer 1: a = %d, b = %d\n", a, b);
    a ^= b ^= a ^= b;
    printf("variables: a = %d, b = %d\n", a, b);
    *pa ^= *pb ^= *pa ^= *pb;
    printf("pointer 2: a = %d, b = %d\n", a, b);
    return 0;
}

結果は

pointer 1: a = 5, b = 3
variables: a = 3, b = 5
pointer 2: a = 0, b = 3

*pa ^= *pb ^= *pa ^= *pbなぜうまくいかないのか知りたいです。誰でも教えてもらえますか?

4

3 に答える 3

7

割り当て間にシーケンス ポイントはありません。

*pa ^= *pb ^= *pa ^= *pb;

したがって、動作は定義されていません。

割り当て間にシーケンス ポイントもありません。

a ^= b ^= a ^= b;

したがって、その行の動作も未定義です。それがたまたまうまくいった場合、あなたは(不)幸運でした。

于 2013-11-14T07:43:16.563 に答える
3

間にシーケンス ポイントが必要です。それ以外の場合、これは未定義の動作です。

于 2013-11-14T07:43:27.850 に答える
1

質問に答える前に、次のことを紹介します。

シーケンスポイント:

シーケンス ポイントは、ほこりが落ち着いた時点で、これまでに見られたすべての副作用が完全であることが保証されています。

規格には次のように記載されています。

前のシーケンス ポイントと次のシーケンス ポイントの間で、オブジェクトの格納値は、式の評価によって最大 1 回変更されます。さらに、以前の値は、保存する値を決定するためにのみアクセスされます。

さて、あなたの問題は、式で

a ^= b ^= a ^= b;  

 *pa ^= *pb ^= *pa ^= *pb;  

シーケンス ポイント (式の最後)は 1 つしかなく、最初の式と2 つのシーケンス ポイント (ここではこれらの式の前と最後) の間の 2 番目の式で 2;変更しているため、プログラムundefinedの動作が発生します。a *pa;;

詳しく読む: comp.lang.c FAQ リスト · 質問 3.8 .

于 2013-11-14T07:56:08.023 に答える