5.演算子

5-4. 代入演算子・複合代入演算子

◆代入演算子

意外とこれは重要で数学の常識から外れています。

=はイコールでなく単なる右から左への代入なのです!(強調)
それがわからなかったために小学3年生プログラマー(昔の自分)は絶望しました。

というわけでここはプログラミング初心者には絶対理解しておかなければ超えることのできない垣根です。(言語を問わず同じ垣根)

a = 1

とか、

a = 1 + 3

ならばまだ話はわかります。
しかし、

a = a + 1

となった時はどう考えてもイコールではないですね。
ここで当時の自分はつまづいてしまいました。
(当時はコンピュータはマイコンでOSも言語もBASICでしたが…)

……で、=の意味は右辺を左辺の変数に代入するということなので、上の式はaを1増やしてその値をaに代入する、つまりaの値を1増加させていることになります。

そのほか決まりとして左辺の項は1つだけでかつ変数などの格納できるものでないといけないことです。

例でいうと、

a + b = c + d /* 左辺が二項あって代入できない */

2 = a + b + c /* リテラルには代入できない */

ということです。

また、=はならべて使うことができます。

X = Y = Z = 0

数学的ですね。もちろん右から左へ代入するので最初にZが0になり、次にYが0になり、最後にXが0になります。

ここで上で説明した決まりを適用すると一番右の辺のみがリテラルや式が許されることになります。

X = Y + 1 = Z = 8 /* 波線の部分は不正な辺になる */
~~~~~

その他、注意すべきことは代入するものとされる変数のデータ型を合わせることです。
エラーはでなかったけれど計算結果がおかしいというときはだいたい代入の時点で右辺と左辺のデータ型が不一致でデータが欠損していることが多いのです。
(コンパイラーによって警告がだされるので気づくとは思いますが…)

では、プログラミングしてみましょう。

#include<stdio.h>

main()
{
    int a,b,c,d;

    a = 3;
    b = 2;
    c = 9;
    d = -8;

    printf("a = %d\nb = %d\nc = %d\nd = %d\n",a,b,c,d);

    c = a + b;
    d = a - b;

    printf("c = a + b -> %d\n",c);
    printf("d = a - b -> %d\n",d);
}

結果:
a = 3
b = 2
c = 9
d = -8
c = a + b -> 5
d = a – b -> 1

と表示されたと思います。

◆複合代入演算子

まずは演算子の記号の紹介から、

加算 +=
減算 -=
乗算 *=
除算 /=
余剰 %=

の5つを紹介します。この他にもありますがそれはビット演算子なので後回しにします。

たとえば、

a = a + 2

という式があるとき要はaの値を2増加させたいだけなのでもっと簡単な書き方はないのかなっと、このとき複合演算子をつかうと次のようになります。

a += 2

このようにして式の記述量を減らすためにあります。

aを3減らしたいならば、

a -= 3

4倍にするには、

a *= 4

10分の1にするには、

a /= 10

そして、3で割った余りを代入する時は、

a %= 3

となります。

それぞれ、
a = a – 3
a = a * 4
a = a / 10
a = 1 % 3

と対応しています。

複合代入演算子も複数使うことができます。

a += b -= c *= d /= e %= 4

ここで各変数の初期値が

a = 2, b = 3, c = 4, d = 6, e = 7

だった場合演算結果はどうなり各変数の値は何になるでしょうか?

#include<stdio.h>
main()
{
    int a = 2, b = 3, c = 4, d = 6, e = 7;

    a += b -= c *= d /= e %= 4;

    printf("a = %d\nb = %d\nc = %d\nd = %d\ne = %d\n",a,b,c,d,e);
}

結果:
a = -3
b = -5
c = 8
d = 2
e = 3

となりました。

さて、昨日の宿題

#include<stdio.h>
main()
{
    int a = 2, b = 3, c = 4, d = 6, e = 7;

    a += b -= c *= d /= e %= 4;

    printf("a = %d\nb = %d\nc = %d\nd = %d\ne = %d\n",a,b,c,d,e);
}

結果:
a = -3
b = -5
c = 8
d = 2
e = 3

引き続き解説をします。

まずは右から代入していくので、
e %= 4
eは7なので、e %= 4 は3になりeには3が代入されます。

次に、d /= e
この時のdは6、eは3なので d /= e は2になりこれがdに代入される。

そして、c *= d
cは4、dは2なので c *= d は8これがcに代入される。

さらに続いて、b -= c
bは3、cは8なので b -= c は-5になりbに代入される。

最後にa += b
aは2、bは-5なので a += b は-3、これがaに代入される。

またこれ以上式がないのでこの値が式全体の値として存在します。

a += b -= c *= d /= e %= 4 ←この式全体の値は-3
~~~~~~~~~~~~~~~~~~~~~~~~~~