タイトルが示すように、いくつかの C の講義ノートでそのような文を見つけました。
その文を証明する例を発明することはできません。
私の意見では、すべての代入操作は一度評価されます。これは、複数回評価したい場合はループに入れるためです。私は何が欠けていますか?
検索しましたが、SOで答えが見つかりませんでした。
タイトルが示すように、いくつかの C の講義ノートでそのような文を見つけました。
その文を証明する例を発明することはできません。
私の意見では、すべての代入操作は一度評価されます。これは、複数回評価したい場合はループに入れるためです。私は何が欠けていますか?
検索しましたが、SOで答えが見つかりませんでした。
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
.
通常、+=
演算子は次のように導入されます。
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 回実行されることです。
あなたの質問は非常に不明確で言葉遣いが不十分ですが、あなたのメモが参照していたのは、算術演算子と代入演算子を組み合わせることで、左辺値の式を複数回書く(したがって評価する)ことなく特定のことを実行できるということだと思います。例えば、
*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 */
ハンディでコンパイルするものは何もありませんが、ここに興味深い情報があります:
var1 += var++
var1 の値をvar1 + var
でも
var1 += ++var
var1 の値をvar1 + (var + 1)
C には、+=、-=、*=、/=、%= などの複合代入演算があります。
例えばi += 1の場合i++のようにiの値を 1 ずつ増やします。
多数の複合代入演算子があります。たとえば。+=,-=,*=,/=,%=
詳細については、これをクリックしa+=b
てくださいgive a=a+b