演算子 Java 基本3

modified at:08 March 2016

算術演算子と単項演算子

演算子 記入例 説明
+ x + y xとyを加算します。
- x - y xからyを減算します。
* x * y xをyで乗算します。
/ x / y xをyで除算します。
% x % y xをyで除算した余りを求めます。
++ インクリメント ++x x++ ++xはxを1増加させた後に文を評価します。 x++は文を評価した後に1増加させます。
-- デクリメント --x x-- --xはxを1減少させた後に文を評価します。 x--は文を評価した後に1減少させます。

通常の四則演算に加えて、割り算の余りを出す「%」、単項演算子といわれる「インクリメント」と「デクリメント」があります。「インクリメント」と「デクリメント」は「++」と「––」の書く場所が、前だと1を足したり引いたりした後に代入等の式を評価し、後ろだと代入等の式を評価した後で1を足したり引いたりします。

「++と--」の変数の前か後かによる挙動の違い
xの初期値 代入後のxの値 代入後のyの値 解説
1 int y = ++x; 2 2 xを1増やしてから、代入
1 int y = x++; 2 1 yに代入してから、1増やす
1 int y = --x; 0 0 xを1減らしてから、代入
1 int y = x--; 0 1 yに代入してから、1減らす

代入演算子と複合代入演算子Topへ

代入演算子「=」は、右辺の値を左辺に代入する時に使用します。また、少し便利な「+」や「-」と組み合わせた複合代入演算子というものも用意されています。複合代入演算子は、演算と代入を一つの演算子にまとめたものです。

種別 演算子 説明 算術演算子による記述
代入演算子 = a = b aにbを代入する。  
複合代入演算子 += a += b aにbを加えた値をaに代入する。 a = a + b
-= a -= b aからbを引いた値をaに代入する。 a = a - b
*= a *= b aとbをかけた値をaに代入する。 a = a * b
/= a /= b aをbで割った値をaに代入する。 a = a / b
%= a %= b aをbで割って余った値をaに代入する。 a = a % b

複合演算子は、例えば本来の「x = x + 12;」という書き方に対して、「x += 12;」のような、より簡単な書き方のことです。なお、このような「プログラムの意味としては同じものを、よりわかりやすい構文で書ける」ものを「シンタックスシュガー(糖衣構文)」といいます。

代入演算子と複合代入演算子の例
1 int x = 1;
2 int y = 10;
3 x = y;   // x = 10
4 x += 12; // x = 22
5 x -= 2;  // x = 20
6 x *= 10; // x = 200
7 x /= 40; // x = 5
8 x %= 2;  // x = 1
9 System.out.println("計算結果:" + x); // 計算結果:1と出力されます。

関係演算子Topへ

関係演算子は、2つの値を比較する時に用いるもので、その比較の結果を真(true)、偽(false)で返します。つまり、その比較が正しいと「true」を返し、間違えていると「false」を返すわけです。

関係演算子 説明
> x > y xがyよりも大きい場合、trueを返します。そうでなければfalseを返します。
>= x >= y xがyよりも大きいか等しい場合(xがy以上)、trueを返します。そうでなければfalseを返します。
< x < y xがyよりも小さい場合(xがy未満)、trueを返します。そうでなければfalseを返します。
<= x <= y xがyよりも小さいか等しい場合(xがy以下)、trueを返します。そうでなければfalseを返します。
== x == y xとyが等しい場合、trueを返します。そうでなければfalseを返します。
!= x != y xとyが等しくない場合、trueを返します。そうでなければfalseを返します。
instanceof x instanceof y xがyと同じクラスかyのサブクラスである場合、trueを返します。そうでなければfalseを返します(サブクラスは後述)。

下のコード2行目で「(x == y)」は、xとyが1なのでtrueを返し、System.out.println内ではbooleanのtrueは「trueという文字列」に自動で変換される結果、「x == y:true」と出力されます。

関係演算子の例1
1 int x = 1; int y = 1; int z = 3;
2 System.out.println("x == y:" + (x == y)); //xとyは同じなのでtrueが出力されます。
3 System.out.println("x == z:" + (x == z)); //xとzは違うのでfalseが出力されます。
4 System.out.println("x != y:" + (x != y)); //xとyは違わないのでfalseが出力されます。
5 System.out.println("x != z:" + (x != z)); //xとzは違うのでtrueが出力されます。
6 System.out.println("x <= y:" + (x <= y)); //xはy以下なのでtrueが出力されます。
7 System.out.println("x < z:" + (x < z));   //xはzより小さいのでtrueが出力されます。
8 System.out.println("x >= y:" + (x >= y)); //xはy以上でなのでtrueが出力されます。
9 System.out.println("x > z:" + (x > z));   //xはzより大きくないのでfalseが出力されます。

なお、現場のコーディング規約にもよりますが、一般に「<」が推奨されている場合があります。数直線的に考えると左の方が小さく、右の方が大きい、というのが自然な感じがして、直感的にわかりやすいからです。また、不等号の向きが統一されて、わかりやすくもなります。

論理演算子Topへ

2つ以上の条件を元に、評価したい場合に利用します。具体的には「日本人で、かつ女性で、かつ30歳以上の人」というような条件を作りたい場合です。

論理演算子 説明
&& a && b aとbがともにtrueの時にtrue、そうでなければfalseを返します。
& a & b 「&&」とほぼ同じですが、aがfalseでもbを評価します。
|| a || b aかb の少なくとも1つがtrueの場合にtrue、1つもtrueがなければfalseを返します。
| a | b 「||」とほぼ同じですが、aがtrueでもbを評価します。
! !a aがtrueの場合にfalse、aがfalseの場合にtrueを返します。

下のコードは、すでに学んだ「前置/後置インクリメント」を使い、「&」が1つの論理演算子と2つの「&&」との違いを確認しています。

論理演算子の例1
 1 // 「;(セミコロン)」を書けば、1行にいくつもの文を書けます。
 2 int a = 1; int b = 1;
 3 
 4 /*
 5  * ・前置インクリメントは比較する前、後置インクリメントは比較してからインクリメントします。
 6  * ・&amp;は1つでもfalseだったら、後半何であれfalseになりますが、文の評価はされます。
 7  * ※コメントは「/*」〜「*/の間で複数行にわたって書けます
 8  */
 9 boolean result = ++a <= 1 &amp; b++ <= 1;
10 
11 // result:false, a:2, b:2と出力されます。
12 System.out.println("result:" + result + ", a:" + a + ", b:" + b);

「++a <= 1」は前置インクリメントなので、インクリメントしてから比較をします。すなわち「a」が2になってから、1以下かどうかを評価していますので、「false」になります。これで「++a <= 1 & b++ <= 1」は全体として「false」になることが決定されます。

しかし「&」は後半の「b++ <= 1」も評価されますので(インクリメントの前に評価するので「true」ですが結果は変わりません)、文の評価後にはbは2になっています。

次は「&&」の例です。

論理演算子の例2
 1 int a = 1; int b = 1;
 2 
 3 /*
 4  * ・前置インクリメントは比較する前、後置インクリメントは比較してからインクリメントします。
 5  * ・&amp;&amp;は1つでもfalseだったら、後半何であれfalseになり、それより後の文は評価されません。
 6  */
 7 boolean result2 = ++a <= 1 &amp;&amp; b++ <= 1;
 8 
 9 // result2:false, a:2, b:1と出力されます。
10 System.out.println("result2:" + result2 + ", a:" + a + ", b:" + b);

上のコードは論理演算子が「&&」であること以外は「&」のコードと同じです。すなわち最初の「++a <= 1」で「false」になり、全体として「false」になることが決定します。そして「&」と違い、「b++ <= 1」は評価されないので、bは1のままになっています。

演算子の優先順位Topへ

「算術演算子」である「+」や「×(*)」は計算する順番が決まっています。例えば「5 + 3 × 5 = 20」という計算の場合、 先に「3 × 5」を計算します。この「+」より「×」を先に計算するようなルールを「演算子の優先順位」といいます。Javaでは演算子の優先順位は次のようになってます。

演算子の優先順位
優先順位 演算子 名前 結合規則
1 () 引数
[] 配列アクセス
. メンバアクセス
++ 後置インクリメント
-- 後置デクリメント
2 ! 論理否定
~ 補数(ビットの反転)
+ 符号のプラス
- 符号のマイナス
++ 前置インクリメント
-- 前置デクリメント
3 new オブジェクト生成
() キャスト
4 * 乗算
/ 除算
% 剰余
5 + 加算
- 減算
6 << 左シフト
>> 右シフト
>>> 符号なし右シフト
7 > より大きい
>= 以上
< より小さい
<= 以下
instanceof 型比較
8 == 等価
!= 非等価
9 & ビット論理積
10 ^ ビット排他的論理和
11 | ビット論理和
12 && 論理積
13 || 論理和
14 ?: 条件
15 = 代入
+= 加算代入
-= 減算代入
*= 乗算代入
/= 除算代入
%= 剰余代入
&= 論理積代入
|= 論理和代入
^= 排他的論理和代入
<<= 左シフト代入
>>= 右シフト代入
>>>= 符号なし右シフト代入

先の例をJavaの代入文にすると、次のようになります。

算術演算子の優先順位の例
1 int a = 5 + 3 * 5;

演算子「*+=」は表から、優先順位が「*」「+」「=」の順ですので、「3 * 5」が先に計算され、次に「5 + 15」が計算され、そして、最後に計算結果の20がaに代入されるのです。

「5 + 3」の方を先に計算させたい場合は次のように「()」を使います。

算術演算子の優先順位の変更例
1 int a = (5 + 3) * 5;

さて、次のような、同じ優先順位の演算子がいくつか使われている場合はどうなるのでしょうか?

結合規則の考え方1
1 int a = 100 / 5 * 3

上の例では、「/」と「*」の優先順位が同じなので、このままではどちらから計算すべきがわかりません。そこで「結合規則」というものがあり、この結合規則は「/や*」の場合「左」なので、左の方から順番に計算していきます(右というのもす)。結果的に、次のような「()」のある計算と同じになります。

結合規則の考え方2
1 int a = (100 / 5) * 3

ただ、結合規則が「左」というのは小学生で習った計算の順番と同じなのでわかりやすいですが、「右」の例を見てみましょう。

結合規則の考え方3
1 int x;
2 int y;
3 
4 x = y = 100;

一番下の行の「=」が2つあってちょっと奇異な印象がありますが、「=」も上の表にもある代入演算子で結合法則は「右」です。それにしたがい順番に考えれば単純です。当然「=」と「=」は優先順位が同じで、結合規則は「右」なので、右の方から評価されます。

結合規則の考え方4
1 x = (y = 100);

つまり上のようにまずは「y = 100」が評価されます(yに100が代入されます)。そして次に、そのyをxに代入することになります(このような代入文を多重代入といいます)。

  created at:06 July 2015




[投稿する]場合は、 枠の中の図形をマウスでドラッグして、(あるいは指で)なぞって下さい。それほど厳密でなくても大丈夫です。