java学び直しメモ part2 ～演算子～

## 今回の内容
[前回](http://qiita.com/yuukieiu/items/917a465fb823c889a788)はデータ型について説明しましたが，今回は演算子です．
算術演算子，比較演算子，論理演算子それぞれやっていきます．

## 演算子とは
演算子というのは，算数で使う「+」とか「-」とかの記号のことです．
2つ以上の変数などを組み合わせて，新しい変数を作ったり，条件にあっているかどうか確かめたり，どちらが大きいか比較したりするのに使います．
演算子は，その役割によって大きく3種類に分けられており，**算術演算子，比較演算子，論理演算子**の3つがあります．

## 基本的なルール
演算子を使うときは，2つの項の間に挟むように書きます．
例1）3 + 5
このとき，演算子の左の項と右の項が，**数字同士もしくはブール値同士**でなければいけません．
例1では，両方とも整数なので，データ型で言えばint型です．
なので正しいです．
しかし，次の例は間違いです．
例2）3 + あ
データ型で言えば，「3」はint型，「あ」はchar型（もしくはstring型）です．
演算子の左の項と右の項がデータ型が異なるので，計算できません．
でもint型とdouble型などは，計算可能です（両方とも数字なので）．
そもそも「3」と「あ」を足す意味がわかりませんね．
（javaはchar型をint型にキャストしてくれるので計算自体は出来るんだけど…）
演算子を使うときは，演算子の左の項と右の項が**数字同士もしくはブール値同士**でなければいけない，というルールを覚えましょう．

## 算術演算子
算術演算子は，名前の通り算術を行うための演算子です．
基本として以下の5種類が用意されています

|算術|記号|
|:--:|:--:|
|足し算|+|
|引き算|-|
|掛け算|*|
|割り算|/|
|余り|%|

（javaって「\*\*」で累乗できないんですね．Pythonなら(ry

### 余りを計算する「%」
余りを計算する「%」はmodなんて言いますけど，余りだけを教えてくれます．
例えば，「6 % 3」なんてやると，余りは0なので結果は0です．
「6 % 5」ってやると，余りは1なので結果は1です．

### 割り算の注意点
割り算は，計算するデータ型によって**答えの精度が変わります**．
例えば，int型同士で「5 / 3」をやると，答えもint型になり，「1」となります．
double型同士で「5.0d / 3.0d」をやると，答えもdouble型になり，「1.6666666666666667
d」となります．
このように答えの精度が変わるので，注意が必要です．

### 演算子の優先順位
人間が行う計算同様，演算子にも優先順位があります．
下3つ（*，/，%）は優先順位が高く，上2つ（+，-）は優先順位が低いです．
いつもと一緒ですね．
また，「()」を使って優先順位を変更することができます．
「(5 + 3) * 8」とすると，「5 + 3」が先に計算されます．
これもいつもと一緒ですね．
（どうでもいいですけど，今まで書いたような「計算する2つの数字を計算方法の記号で挟む書き方」のことを「中置記法」と言います．「計算方法の記号のあとに計算する2つの数字を書く書き方」もありまして，これを「ポーランド記法」と言います．興味があったらググってね）

### プログラム例
```java:Sanjutu.java
public class Sanjutu {
    
    public static void main(String[] args) {
        // 変数宣言，初期化
        int x = 8;
        int y = 2;
        int z = 3;
	
        int result01 = x + y;
        System.out.println(x + " + " + y + " = " + result01);
	
        int result02 = x - y;
        System.out.println(x + " - " + y + " = " + result02);
	
        int result03 = y - x;
        System.out.println(y + " - " + x + " = " + result03);
	
        int result04 = x * y;
        System.out.println(x + " * " + y + " = " + result04);
	
        int result05 = x + y * z;
        System.out.println(x + " + " + y + " * " + z + " = " + result05);
	
        int result06 = (x + y) * z;
        System.out.println("(" + x + " + " + y + ") * " + z + " = " + result06);

        int result07 = x / y;
        System.out.println(x + " / " + y + " = " + result07);
	
        int result08 = x / z;
        System.out.println(x + " / " + z + " = " + result08);
	
        int result09 = x % y;
        System.out.println(x + " % " + y + " = " + result09);
	
        int result10 = x % z;
        System.out.println(x + " % " + z + " = " + result10);	
    }

}
```

```sh:実行結果
8 + 2 = 10
8 - 2 = 6
2 - 8 = -6
8 * 2 = 16
8 + 2 * 3 = 14
(8 + 2) * 3 = 30
8 / 2 = 4
8 / 3 = 2
8 % 2 = 0
8 % 3 = 2
```

### インクリメント/デクリメント/再帰代入
拡張的な算術演算子として，インクリメント演算子，デクリメント演算子，再帰代入演算子が用意されています．
**インクリメント**とは，1だけ加算するという意味です．プログラムを書くときにはよく使います．
**デクリメント**は，インクリメントとは逆に1だけ減算するという意味です．これもよく使います．
**再帰代入**は，ある変数に，その変数に何か処理を加えたものを代入して更新するときに使います．たとえば，「x」という変数に，「x + 2」を代入して更新するときに使います．

#### インクリメント/デクリメント演算子
インクリメントするときは，インクリメントしたい変数に「**++**」をつけます．
デクリメントも同様に，デクリメントしたい変数に「**--**」をつけます．
これだけです．
余談ですが，僕の大好きなPythonという言語は，インクリメントやデクリメントができないので，再帰代入演算子を使います．

#### 再帰代入演算子
再帰代入はちょっとわかりづらいかもしれませんが，「再帰代入先の変数 算術演算子= 計算に使う数値」のような書式です．
例として，「x に 3 を足して，それをまた x に代入する」ときは，このように書きます．

```java:SaikiEx.java
// 変数宣言，初期化
int x = 2;
// x に 3 を足して，それをまた x に代入する
x += 3;
```

#### プログラム例
```java:SanjutuExtension.java
public class SanjutuEnzanshi02 {
    
    public static void main(String[] args) {
        // 変数宣言，初期化
        int a = 10;
        int b = -3;
        int c = 24;
        int d = 5;
        int e = 8;

        a += 3;
        System.out.println("a += 3 実行後の a の値:" + a);

        a -= 7;
        System.out.println("a -= 7 実行後の a の値:" + a);
        
        a++;
        System.out.println("a++ 実行後の a の値:" + a);

        a--;
        System.out.println("a-- 実行後の a の値:" + a);

        b *= 4;
        System.out.println("b *= 4 実行後の b の値:" + b);

        b++;
        System.out.println("b++ 実行後の b の値:" + b);

        c /= 2;
        System.out.println("c /= 2 実行後の c の値:" + c);

        c /= 4;
        System.out.println("c /= 4 実行後の c の値:" + c);

        d += e;
        System.out.println("d += e 実行後の d の値:" + d);

        d--;
        System.out.println("d-- 実行後の d の値:" + d);
    }

}
```

```sh:実行結果
a += 3 実行後の a の値:13
a -= 7 実行後の a の値:6
a++ 実行後の a の値:7
a-- 実行後の a の値:6
b *= 4 実行後の b の値:-12
b++ 実行後の b の値:-11
c /= 2 実行後の c の値:12
c /= 4 実行後の c の値:3
d += e 実行後の d の値:13
d-- 実行後の d の値:12
```

## 比較演算子
比較演算子は，2つの項を比較して，大小を比べたり，等しい値かを比べたりして，結果を「true」か「false」の**真偽値**で教えてくれる演算子です．
2つが等しかったらこの処理をする，とか，こっちが大きかったらこの処理をする，というときに使います．
次の6つが用意されています．

|意味|記号|
|:--:|:--:|
|<|小なり|
|>|大なり|
|<=|以下|
|>=|以上|
|==|等しい|
|!=|等しくない|

「==」と「=」は似ていますが，前者は等しいかどうかの「**比較**」，後者は変数に「**代入**」するという意味で，全く別物です．
javaには無いですが（うろおぼえ），「===」という演算子がある言語もあって，値だけじゃなくて型まで等しくないとtrueにならないような比較演算子もあります（うろおぼえ）．
Pythonには「is」という演算子がありまして，これもまた「==」と似たような演算子でして…

### プログラム例
```java:Hikaku.java
public class HikakuRonriEnzanshi01 {
    
    public static void main(String[] args) {
        // 変数宣言，初期化
        int a = 15;
        int b = 8;
        int c = 2;
        int d = 3;

        boolean result01 = (a == 15);
        System.out.println("a == 15 の判定結果:" + result01);

        boolean result02 = (a != 15);
        System.out.println("a != 15 の判定結果:" + result02);

        boolean result03 = (b > 8);
        System.out.println("b > 8 の判定結果:" + result03);

        boolean result04 = (b >= 8);
        System.out.println("b >= 8 の判定結果:" + result04);

        boolean result05 = (d < c);
        System.out.println("d < c の判定結果:" + result05);

        boolean result06 = (d <= a);
        System.out.println("d <= a の判定結果:" + result06);
    }

}
```

```sh:実行結果
a == 15 の判定結果:true
a != 15 の判定結果:false
b > 8 の判定結果:false
b >= 8 の判定結果:true
d < c の判定結果:false
d <= a の判定結果:true
```

もちろん，真偽値同士でも比較できますよ．
文字列はちょっと違うけど…

## 論理演算子
論理演算子は論理式を表すのに使います．
これも結果は「true」か「false」の真偽値です．
論理式というのは，論理積（～かつ～）とか論理和（～または～）みたいなやつです．ググれ．
以下の4つが用意されています．

|論理式|記号|
|:--:|:--:|
|論理積（AND）|&&|
|論理和（OR）|&#124;&#124;|
|排他的論理和（XOR）|^|
|否定（NOT）|!|

排他的論理和はめったに使いませんので省略…

### プログラム例
```java:Ronri.java
public class Ronri {
    
    public static void main(String[] args) {
        // 変数宣言，初期化
        boolean a = true;
        boolean b = false;
        int c = 2;
        int d = 3;
        int e = 15;

        boolean result01 = !a;
        System.out.println("!" + a + " = " + result01);

        boolean result02 = !b;
        System.out.println("!" + b + " = " + result02);

        boolean result03 = !!b;
        System.out.println("!!" + b + " = " + result03);

        boolean result04 = !(c == 2);
        System.out.println("!(d == 3) の判定結果:" + result04);

        // 比較演算子と組み合わせて使ってみる

        boolean result05 = c > d && e == 8;
        System.out.println("c > d && e == 8 の判定結果:" + result05);

        boolean result06 = c < d && e != 8;
        System.out.println("c < d && e != 8 の判定結果:" + result06);

        boolean result07 = c > e || e >= 15;
        System.out.println("c > e || e >= 15 の判定結果:" + result07);

        boolean result08 = c > e || e > 15;
        System.out.println("c > e || e > 15 の判定結果:" + result08);

        boolean result09 = c >= 10 && c < 20;
        System.out.println("c >= 10 && c < 20 の判定結果:" + result09);

        boolean result10 = d <= 5 || e >= 10;
        System.out.println("d <= 5 || e >= 10 の判定結果:" + result10);	
    }

}
```

```sh:実行結果
!true = false
!false = true
!!false = false
!(d == 3) の判定結果:false
c > d && e == 8 の判定結果:false
c < d && e != 8 の判定結果:true
c > e || e >= 15 の判定結果:true
c > e || e > 15 の判定結果:false
c >= 10 && c < 20 の判定結果:false
d <= 5 || e >= 10 の判定結果:true
```

あー難しい．（笑）

### 比較，論理演算子の優先順位
プログラムを見てわかると思いますが，論理演算子よりも比較演算子のほうが優先されています．なので先に論理演算したいときは「()」でくくってあげる必要があります．

## おわり
今回紹介した演算子はよく使うものばかりですが，他にもいくつか用意されています．
ちょっとわかりにくいけどとっても便利な三項演算子とか…
次回で演算子（特に比較演算子）を多用することになると思うので，最低限今回紹介した演算子はきちんと使い方をマスターしておきたいところです．