4

ええと、私はこの答えを真剣に必要としているわけではありません。私はただ好奇心旺盛です。

のような式*ptr++ = aは完全に有効です。なぜなら、2 つのオブジェクトを操作しているからptrです。*ptr*ptr++ = *ptr + a

たとえば、次のスニペットを考えてみましょう。

int main(void){
   int a[] = {5,7,8,9,2};

   int* p =a;

   *p++ = 76; /*altering the first element */
   *p++ = *p + 32; /*altering the second element */    

   p = a;
   int i;
   for(i = 0;i<5; i++)
      printf("%d ",*p++);

   return 0;
}

式に関して心配することは何もないと思いますが、関係する*p++ = *p + 32;シーケンス ポイントについてはわかりません。

4

5 に答える 5

12

の結果*ptr++ = *ptr + aは未定義です。等号はシーケンス ポイントではないためptr、そのステートメントで再度の値を使用すると、未定義の動作が発生します。RHS 式が評価される前に がインクリメントされた場合の結果を考慮し、RHS 式のにがインクリメントされptrた場合と比較します。ptr

注: これは、式の結果がこれら 2 つのシナリオのいずれかから得られるということではありません。未定義は未定義です。

基本的に、ポストインクリメントが最後のシーケンスポイントと次のシーケンスポイントの間のある時点で評価されること、および式がインクリメントされる前ptr++の値を返すことの 2 つしか当てにできません。の結果が当てにできるので、それで問題ありません。ptr *ptr++ = aptr++

于 2009-12-02T08:10:12.530 に答える
8

まず、'p' がポインター型であると仮定します。
それ以外の場合、すべての操作は関数呼び出しの構文糖衣にすぎません。

ステートメントを部分に分解してみましょう。

int* p = a;

*p++ = *p + 32;

<< Sequence Point >>
// Part 1: p++
// Note the definition of post increment in the standard is (5.2.6)
// The result of the expression p++ is the value of 'p' while the value of the 
// objects represented by 'p' is incremented. This can be represented in pseudo code as:
(A) int*  p1 = p;
(B) p = p + 1;

// Part 2: *p (On the result of Part 1) (On *p++)
(C) int& p2 = *p1;  // Note the use of p1;

// Part 3: *p (On *p + 32)
// Note: There is no linkage between this use of 'p' and the 'p' in Part 1&2
(D) int& p3 = *p;

// Part 4: *p + 32;
(E) int p5 = p3 + 32; // Note the use of p3;

// Part 5: Assignment.
(F) p2 = p5;
<< Sequence Point >>

Ordering that must be preserved:
(A) Before (B)
(A) Before (C)
(D) Before (E)
(C) Before (F)
(E) Before (F)

上記の制約を考えると、
コンパイラはこれらの命令をいくつかの方法で並べ替えることができますが、
注意すべき主なポイントは、(B) の唯一の制約は (A) の後に発生するということです。 (D) で定義されている p3 は、(B) の正確な位置に応じて、2 つの異なる値のいずれかになります。

p3 の値はここでは定義できないためです。
結果のステートメントには未定義の動作があります。

于 2009-12-02T10:33:55.690 に答える
1

Cに関しては、*ptr++ = *ptr + 326.5.2に従って未定義になります。「スカラーオブジェクトに対する副作用が、同じスカラーオブジェクトに対する異なる副作用、または同じスカラーオブジェクトの値を使用した値の計算に関連してシーケンスされていない場合、動作は未定義です。」ptrシーケンスポイントを介在させずに、 の値を変更して別の計算で使用しようとしています。

于 2009-12-02T14:03:11.680 に答える
0

あなたが求めているのは同じではありません。それはコンパイルされますが...

PTR がその配列の最後のセルではなく配列を指している場合、それは正当です。そのため、PTR をインクリメントすると、配列内の次のオブジェクトが指されます。

*ptr++ = *ptr + 2 は、*ptr = *ptr + 2, ptr++ と同じです。

于 2009-12-02T08:03:48.110 に答える
0

未定義だと思います。しかし、私は確かではありません。

しかし、少し広い文体のポイント: 式が未定義であるかどうか疑問に思うようになった場合、これはコードの意図が明確ではないことを示している可能性があり、あいまいさを減らし、明白でない依存関係を少なくする必要があります。評価の順序。

私は C 言語が本当にクールだと思っていました。もうそうは思わない。:-)

于 2009-12-02T08:09:46.757 に答える