3

タイトルが示すように、いくつかの C の講義ノートでそのような文を見つけました。

その文を証明する例を発明することはできません。

私の意見では、すべての代入操作は一度評価されます。これは、複数回評価したい場合はループに入れるためです。私は何が欠けていますか?

検索しましたが、SOで答えが見つかりませんでした。

4

6 に答える 6

6

C says:

(C99, 6.5.16.2p3) "A compound assignment of the form E1 op= E2 differs from the simple assignment expression E1 = E1 op (E2) only in that the lvalue E1 is evaluated only once."

Below are some examples of why it matters:

Example 1:

 a[i++] += 1;

is the same as:

 a[i] = a[i] + 1; i++;

because the left operand of += is evaluated once.

If it was not evaluated once it would be the same as:

a[i++] = a[i++] + 1;

which is of course different (and undefined behavior BTW).

Example 2:

*foo() += 1;

assuming foo here returns a pointer to an object of a scalar type and produces side effects (for example it prints a string on the terminal). With the compound assignment operator it will print the string only once and not two times.

Example 3:

REG |= 0x01;

assuming REG here is an IO register (something like #define REG (*(volatile uint8_t *) 0x42)) and that every read to this specific IO register triggers a hardware event. The register will be read only once with the compound assignment operator and not two times.

EDIT: following @R. comment I striked the example 3. I think most compilers do not perform a read in this expression: REG = 31 or two reads with this expression: REG = REG | 0x01.

于 2012-08-26T20:43:37.677 に答える
2

通常、+=演算子は次のように導入されます。

x += y;
x = x+y; // does the same

=ただし、注記では、 andの左側+=が任意の式である可能性があるため、これは実際には正確ではないことを伝えようとしています。他の人が述べているように、これは未定義の動作につながる可能性がありますが、それは問題の核心ではありません。

例えば:

char* f() {
  static char value = 'a';
  printf("%c\n",value);
  return &value;
}

void g() {
  *f() = 'b'; // assigns 'b' which was 'a'
  *f() += 2; // changes 'b' to 'd'
  *f() = 'b';
  *f() = *f() + 2; // changes 'b' to 'd'
}

違いはf、最後の行で 2 回実行されるのに対し、2 番目の行では 1 回実行されることです。

于 2012-08-26T21:03:02.500 に答える
1

あなたの質問は非常に不明確で言葉遣いが不十分ですが、あなたのメモが参照していたのは、算術演算子と代入演算子を組み合わせることで、左辺値の式を複数回書く(したがって評価する)ことなく特定のことを実行できるということだと思います。例えば、

*p++ += *q++;  /* p is incremented once, as desired */
*p++ = *p++ + *q++;  /* undefined behavior */

たとえば、マクロでこれらを使用する場合は特に重要です。

#define ACCUM(d,s) (d)+=(s) /* good */
#define ACCUM(d,s) (d)=(d)+(s) /* dangerous */
于 2012-08-26T20:45:53.753 に答える
0

ハンディでコンパイルするものは何もありませんが、ここに興味深い情報があります:

var1 += var++var1 の値をvar1 + var

でも

var1 += ++varvar1 の値をvar1 + (var + 1)

于 2012-08-26T20:59:12.457 に答える
0

C には、+=、-=、*=、/=、%= などの複合代入演算があります。

例えば​​i += 1の場合i++のようにiの値を 1 ずつ増やします。

于 2012-08-26T20:59:22.527 に答える
0

多数の複合代入演算子があります。たとえば。+=,-=,*=,/=,%=

詳細については、これをクリックしa+=bくださいgive a=a+b

于 2013-02-12T19:31:58.157 に答える