5章 演算子
1.演算子の種類
 ●演算子
   ○算術演算子
    ・四則演算子         +,-,*,/,%
    ・符号変換           -
   ○比較演算子
    ・大小比較           <,>,<=,>=
    ・等価、非等価         ==,!=
   ○論理演算子
    ・論理否定           !
    ・論理積            &&
    ・論理和            ∥
   ○インクリメント演算子     ++
   ○デクリメント演算子      –
   ○ビット演算子
    ・論理積            &
    ・論理和            |
    ・排他的論理和        ^
    ・論理否定(1の補数)    ~
   ○シフト演算子
    ・左シフト            <<
    ・右シフト            >>
   ○代入演算子
    ・代入              =
    ・四則演算           +=,-=,*=,/=,%=
    ・シフト演算           <<=,>>=,>>>=
    ・ビット演算           &=,|=,^=
   ○cast演算子           (型) 例えば、(int),(char)など
   ○順次演算子            ,
   ○条件演算子(三項演算子)   ? : 
   ○instanceof演算子       instanceof
 
2.インクリメント演算子、デクリメント演算子
   int i;
       for( i = 0 ; i < 10 ; i = i +1 )
             System.out.println(i);
上記の例のように、今まで変数を1増やす場合「 i = i + 1 」と書いてきた。しかし「変数を1増やす」という作業は頻繁に行われるため、特別の演算子が用意されている。上の例は、その演算子を使用すると下記のようになる。
   int i;
       for( i = 0 ; i < 10 ; i++ )
             System.out.println(i);
この「++」がインクリメント演算子である。逆に「変数の値を1減らす」演算子はデクリメント演算子といい「――」である。
この演算子は「i++」のように変数の後に書くことも、「++i」のように変数の前に書くこともできる。しかし「j=i++」のように式の中に組み込むと、変数の前に書いた場合と、変数の後に書いた場合の動作が異なる。変数の前に書いた場合は、式を評価する前にインクリメントする。逆に変数の後に書いた場合は、式を評価した後にインクリメントする。
import java.io.*;

    public static void main( String args[ ] ){
        int a,b;
        a = 3;
        b = ++a;

        System.out.println("a=" + a + " b=" + b);
    }
}

import java.io.*;

class Test{
     public static void main(String args[ ] ){
        int a, b;
        a = 3;
        b = a++;

        System.out.println("a=" + a + " b=" + b);
    }
}

D:\java>javac Test.java

D:\java>java Test

a=4 b=4

D:\java>

D:\java>javac Test.java

D:\java>java Test

a=4 b=4

D:\java>

 一つの式の中に同じ変数に対するインクリメント演算子が複数あってはならないということである。もちろんデクリメント演算子も同じ注意がある。
例えば、「b=a++ +a++」というのはダメ。予期しない結果になることが多く、バグを招き兼ねない。「printf("%d %d\n",++a,++a);」というのもダメ。
import java.io.*;

class Test{
    public static void main(String args[ ] ){
       int a, b;
       a = 0;
       b = ++a + ++a;

        System.out.println("a=" + a + " b=" + b);
    }
}

import java.io.*;

class Test{
     public static void main(String args[ ] ){
        int a, b;
        a = 0;
        b = a++ + a++;

        System.out.println("a=" + a + " b=" + b);
    }
}

D:\java>javac Test.java

D:\java>java Test

a=2 b=3

D:\java>

D:\java>javac Test.java

D:\java>java Test

a=2 b=1

D:\java>

 
3.複合代入演算子
 複合代入演算子とは、演算と代入を一つの演算子にまとめたものである。インクリメント演算子やデクリメント演算子も複合代入演算子の一種ということができる。
複合代入演算子 使用例 意味 普通の演算子
+= 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
>>>= 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
^= a^=b; aとbの排他的論理和をaに代入する a=a^b
         
4.ビット演算子
演算子 意味 使用法
& ビット積(AND) a=b&c; bとcの各ビット毎の論理積をとり、その結果をaに代入する
| ビット和(OR) a=b|c; bとcの各ビット毎の論理和をとり、その結果をaに代入する
^ ビット排他的論理和(XOR) a=b^c; bとcの各ビット毎の排他的論理和をとり、その結果をaに代入する
~ ビット否定(NOT) a=~b; bの各ビットを反転しその結果をaに代入する
AND      
b c 結果(a)  
0 0 0  
0 1 0  
1 0 0  
1 1 1  
AND演算はビットを0でマスクするのに使用する。マスクとはあるビットを0もしくは1に変えること。例えば、奇数か偶数かを調べるためには、最下位を残して0でマスクする。その値が1なら奇数、0なら偶数ということになる。
import java.io.*;

class Test{
     public static void main(String args[ ]) {
         int i = readNumber( );

         if ( i = & 1 == 1 ) {
              System.out.pringtln("奇数です");
    }
         else{
              System.out.println("偶数です");
    }
  }

    // キーボードから数字を入力するメソッド
  public static int readNumber( ){
        byte b[ ] = byte [100];

        try{
              System.out.println.in.read(b);
            return Integer.parseInt((new String( (b).trim( ) ).trim( ) );
        }catch(Exception e) {
                return 0;  
          }
     }
}

OR      
b c 結果(a)  
0 0 0  
0 1 1  
1 0 1  
1 1 1  
OR演算はビットを1でマスクするのに使用する。
XOR      
b c 結果(a)  
0 0 0  
0 1 1  
1 0 1  
1 1 0  
XOR演算はビットを必要な部分だけ反転させるのに使用する。
NOT      
b 結果(a)    
0 1    
1 0    
NOT演算は1の補数を表す。1の補数とはすべてのビットを反転する。
 
5.シフト演算子
 シフト演算とは論理演算と同じようにビットを操作する命令である。具体的には、2進数の各ビットをずらすことである。右にずらすか左にずらすか、符号なしか、符号付きかによって3種類の演算子が用意されている。
演算子  意味 使用法
<< 左にシフト a = b << c bを左にcビットずらす
>>  右にシフト a = b >> c bを右にcビットずらす(符号付き)
>>> 右にシフト a = b >> c bを右にcビットずらす(符号なし)
0000 0001 = 1        1111 1111 = -1
   ↓                         ↓
0000 0010 = 2        1111 1110 = -2
       ↓            ↓
0000 0100 = 4           1111 1100 = -4

      整数          負数
このように左にずらすと、その値は2倍になる。
 
6.キャスト演算子
 キャストとは「型変換」のこと。下の例のように代入元と代入先の変数の型が異なる場合、型変換を行う必要がある。一般に「byte」型から「int」型への変換など、小さい入れ物から大きな入れ物へは自動的にキャストされる。これを「暗黙の型変換」という。
   int    i = 100;
   byte b = 100;

  i = b;            // 暗黙の型変換

 
 逆に大きな入れ物から小さな入れ物へのキャストは、データが失われる可能性があるため、暗黙の型変換は行われずえにエラーが出てしまう。このような場合、コンパイラに「データが失われるかもしれないのは、わかっているよ」と教えなければならない。これを「明示的な型変換」という。
   int    i = 100;
   byte b = 100;

  b = i;            // エラー
  b = (byte)i;  // 明示的なキャスト

 
また、整数と小数(実数)の関係も場合によっては明示的な型変換が必要になる。下の左の例では、明示的な型変換はしていない。右の例では明示的な型変換をしている。キャストしなければ割り算の結果は整数になってしまう。
import java.io.*;

class Test{
    public static void main(String args[ ] ){
       int a = 300;
       float f = a / 7;
 
       System.out.println( f );
    }
}

import java.io.*;

class Test{
     public static void main(String args[ ] ){
        int a = 300;
        float f = (float)a /7;

        System.out.println( f );
    }
}

D:\java>javac Test.java

D:\java>java Test
42.0

D:\java>

D:\java>javac Test.java

D:\java>java Test
42.857143

D:\java>

 
7.順次演算子
 カンマで区切られたいくつかの式を左から順に実行する。このカンマのことを順次演算子という。
import java.io.*;

class Test{
      public static void main(String args[ ]){
      int i;
      int j;

      for ( i = 0, j = 10 ; i < 10 ; i++, j– )
            System.out.println(i*j);
      }
}

 

C:\java>javac Test.java

C:\java>java Test
0
9
16
21
24
25
24
21
16
9

C:\java>java