1

重複の可能性:
これらの未定義の動作を誰かが説明できますか(i = i ++ + ++ i、i = i ++など…)

#include<stdio.h>

int main()
{
  char a[]="Hello";
  char *p=a;
  while(*p)
    ++*p++;     //Statement 2
    printf("%s",a);
    int x=10;
    ++x++; //Statement 1
   return 0;
}

このコードをコンパイルすると、ステートメント1でl値が必要なエラーが発生します。これは理解できます。同じことをするつもりなのに、ステートメント2でエラーが発生しないのはどうしてですか?誰かが光を当てることができますか?

4

3 に答える 3

3

プレインクリメントとポストインクリメントの両方で右辺値が生成され、右辺値は変更できません。

したがって++x++、(ステートメント1)は明らかに制約違反であり、コンパイラーはエラーを出します。

ただし、ステートメント2の場合はそうではありません。p++値を変更できない右辺値を生成しますが、逆参照することはできます。あるいは、これを行うと、ケースと++p++同等になり、エラーが発生します。++x++ここではポインタ自体が変更されているためです。

したがって、次のようになります++(*p++)

(括弧は理解のためだけのものであり、必須ではないことに注意してください。式++*p++は明確に定義されています。)

何が起こるか:

  • ポストインクリメントは、この例でp++はの古い値に評価され、保存されているの値がインクリメントされます。p&a[0]p
  • *p++pこの例では、増分の前にポイントされた値を示しa[0]ます。
  • 最終的なpre-incrementはその値をインクリメントするので、にa[0]なりますI(おそらく、EBCDICマシンでは他の何かである可能性があります)。

pとの増分値a[0]が格納されている場合は指定されていませんが、両方が次のシーケンスポイント(終了;)に格納されている必要があります。

于 2012-12-13T13:40:51.307 に答える
0
#include<stdio.h>

int main()
{
  char a[]="Hello";
  char *p=a;
  while(*p)
    ++*p++;     //Statement 2
    printf("%s",a);
    int x=10;
    ++x=x++; //Statement 1
   return 0;
}

//このコードは、プリインクリメントとポストインクリメントが同時に発生するため、同じエラーをフェッチします。割り当てとインクリメントを同時に行うことはできないため、インクリメントを実行するには値が必要です。

于 2012-12-13T15:33:33.897 に答える
0

ISO C99標準からの引用:

6.5.2.4 Postfix increment and decrement operators

Constraints
1
The operand of the postfix increment or decrement operator shall have qualified or unqualified real or pointer type and shall be a modifiable lvalue.

この場合:

++*p++;     //Statement 2

postfix++は優先順位と接頭辞が高く、優先順位++と結合性*は同じです。right to leftこれは、最初のステップで、値ではなくポインターをインクリメントしていることを意味します。そのため、その次のアドレスが表示されtypeます。そして、value (which is actually *p)インクリメントされます。だから、この場合いいえ constraint violation。と同じ++(*(p++))です。

以下の他の場合:

 int x=10;
 ++x++; //Statement 1

上記の変数(ポインターではない)の場合++(接尾辞または接頭辞のインクリメントまたはデクリメントのいずれか)はrvalue、適用++または--オンrvalueですconstraint violation++または--オペランドは である必要がありlvalueます。上記の標準的な見積もりを参照してください。したがって、エラーが発生します。

于 2012-12-13T13:14:38.723 に答える