代入演算子
単純代入演算
代入演算子 = は、後述する複合代入演算子と区別するために単純代入演算子(Simple assignment operator)と呼ぶこともあります。単純代入演算子は、右項の値を、左項に指定された変更可能な要素に代入します。左項は変数など、変更可能な値でなければなりません。例えば、リテラルに代入することはできません。
10 = 100
上記のような式は無効であり、コンパイルエラーとなります。リテラルは固定値なので、代入で変更することはできません。
変数に保存されている値を変更する代入演算子もまた、算術演算子などと同じような二項演算子に分類されます。従って値の代入は式に該当し、他の式と自由に組み合わせることができます。式を記述できる場所であれば、代入演算が可能です。
System.Console.WriteLine(x = 10);
上記は有効な代入演算です。算術演算をメソッドのパラメータに記述できたように、代入演算も式が書ける場所であれば問題なく指定できます。では、この WriteLine() メソッドが出力する代入演算の結果は何でしょう?
代入式の結果は、変数に格納された値となります。単純代入式の場合、結果は左項に指定された値そのものです。
class Test { static void Main() { int x; System.Console.WriteLine(x = 10); } }
コード1は x 変数に 10 を代入する式の結果を出力しています。x 変数の値を出力しているわけではないので注意してください。
代入演算子は、算術演算子などの他の二項演算子と異なり右結合です。つまり、左項よりも先に右項が実行され、その結果が返されています。代入演算子は右結合で結果を返すため、数珠つなぎで記述できます。例えば、同じ値を複数の変数に代入するときに 1 文で書けます。
class Test { static void Main() { int x, y, z; x = y = z = 10; System.Console.WriteLine(x); System.Console.WriteLine(y); System.Console.WriteLine(z); } }
コード2では x 変数、y 変数、z 変数の値を連続する代入演算式で初期化しています。これらの変数には、すべて 10 が代入されています。
代入演算子は右結合なので、コード2の代入式の実行順序は、以下と同義です。
x = (y = (z = 10))
実行結果からも、代入演算子が右項から評価される右結合の演算子であることが確認できます。
代入演算は他の演算子と同じように演算結果を返しますが、算術演算子などとは異なり変数の値を書き換えるという副作用を持ちます。例えば、リテラルによる加算演算の実行はその場限りの処理であり、他のコードに影響を残しません。しかし、代入演算は代入結果によって、その後のコードに影響を与えます。
この性質を利用して、例えば条件論理演算子の挙動を調べることができます。条件論理演算子の右項に代入演算式を指定すると、左項の結果によっては実行されないことがあります。代入演算式が評価されたかどうかは、代入演算子に指定した変数の値を調べることで確認できます。
class Test { static void Main() { bool x = false, y = false; System.Console.WriteLine((x = true) || (y = true)); System.Console.WriteLine("x=" + x); System.Console.WriteLine("y=" + y); } }
コード3は bool 型の x 変数と y 変数を用意し false で初期化しています。その後、条件論理和演算子の項として代入演算式を指定していますが、左項の結果が true であるため、右項の実行が省略されます。実行結果を見れば、y 変数の値が false のままなので、条件論理和演算子の右項が実行されていないことが確認できます。
複合代入演算
代入演算において、変数の現在の値に対して操作を行いたいということがあります。例えば、変数の現在の値に 5 を加えるといった演算です。単純代入演算子では、以下のように記述できます。
x = x + 5
上記の式のように、代入演算子で左項に指定する変数を、右項の計算に利用することは問題ありません。前述したように、代入演算子は右結合なので、先に代入前の x の値で右項が計算され、その後に計算結果が代入されます。
上記のように単純代入演算子を用いても不都合はありませんが、このような演算には、複合代入演算子(Compound assignment operator)を使うと便利です。
複合代入演算子は op= という形をとります。 op には、何らかの演算子を指定します。
演算子 | 説明 |
---|---|
+= | 加算と代入 |
-= | 減算と代入 |
*= | 乗算と代入 |
/= | 除算と代入 |
%= | 剰余と代入 |
<<= | 左シフトと代入 |
>>= | 右シフトと代入 |
&= | 論理積と代入 |
|= | 論理和と代入 |
`= | 排他的論理和と代入 |
表1は、有効な複合代入演算子の一覧です。上の x の値に 5 を加えるという演算は、複合代入演算子で以下のように記述できます。
x += 5
どちらも結果は同じですが、複合代入演算子を用いたほうが変数の指定で重複がないので間違いがありません。
class Test { static void Main() { int x = 10; x += 5; System.Console.WriteLine(x); } }
コード4の実行結果を見れば、複合代入演算が変数の現在の値に対する計算であることが確認できます。