Previous | Next | Trail Map | Writing Java Programs | Java 言語のナットとボルト


演算子

文字数を数えるプログラムでは、このリストで強調表示した = != ++ + を含む演算子を使用する。
class Count {
    public static void main(String args[])
        throws java.io.IOException
    {
        int count = 0;

        while (System.in.read() != -1)
            count++;
        System.out.println("Input has " + count
+ " chars."
);
    }
}
演算子は1つあるいは 2 つのオペランドに対し、ある機能を実行する。 1つのオペランドを必要とする演算子が単項演算子と呼ばれる。 例えば、 ++ はそのオペランドの値を1増加させる単項演算子である。 2 つのオペランドを必要とする演算子は二項演算子である。 = 演算子は、右辺のオペランドから左辺のオペランドに値を代入する二項演 算子である。

Java の単項演算子はプレフィックスあるいはポストフィックス表記を使用することができる。 プレフィックス表記法は、演算子がそのオペランドの前に現れることを意味する。

operator op

ポストフィックス表記法は、演算子がそのオペランドの後に現われることを意味する 。
op operator

Java の二項演算子のすべてが、演算子がオペランド間に現われることを意味するインフィッ クス表記法を使用する。
op1 operator op2

演算を実行するのに加えて、演算子もまた値を返す。 値とその型は演算子とオペランドの型に依存する。 例えば、算術演算子(加算、減算のような基本的な算術演算を実行する)は、算術演算の典型的な 結果である数を返す。 算術演算子が返すデータ型はそのオペランドの型に依存する。例えば 2 つの整数を加算すれば整数を得る。演算がその結果を評価すると言われる。

Java の演算子を算術、関係と条件、ビットと論理、代入のカテゴリに分けることは有用である。

算術演算子

Java 言語はすべての浮動小数点と整数に対し、 + (加算)、 - (減算)、 * (乗算)、(除算)、 % (モジュロ)を含むさまざまな算術演算子をサポートする。 例えば、2 つの数を加えるには、次のJava コードを使用する。
addThis + toThis

また、 this divideThis を割った余りを計算するには、次のコードを使用する。
divideThis % this

次の表は Java の二項算術演算の一覧である。

Operator    Use
Description
   +     op1 + op2     Adds op1 and op2
   -     op1 - op2     Subtracts op2 from op1
   *     op1 * op2     Multiplies op1 and op2
   /     op1 / op2     Divides op1 by op2
   %     op1 % op2     Computes the remainder of dividing op1 by op2


********** 注釈: Java 言語は文字列連結を組み込むために演算子 + の定義を拡張している 。プログラム例では、"Input has "、 count の値、および " chars." を連結するために、 + を使用している。 この演算は、 countの値を String に自動的に強制するので注意しなさい。
System.out.println("Input has " + count + " chars."
);
配列と文字列でこの詳細を説明する。

+ - 演算子はオペランドの符号を設定するという単項の機能 を持っている。

Operator    Use
Description
   +       + op        [PENDING: what is the effect of this operand?]
   -       - op        Arithmetically negates op

さらに、 2 つのショートカット算術演算子がある。そのオペランドを1増分する ++ と、そのオペランドを1減らす -- である。 文字数を数えるコード例は、 ++ を使用して、入力ソースから1文字読み込むた びに、 count 変数を増分する。

count++ ;
この例では、++ 演算子がそのオペランドの後に現われることに注意しなさい。 これは演算子のポストフィックス表記である。 ++ はまたそのオペランドの 前に現われるプレフィックス表記を持っている。 この演算子のプレフィックスとポストフィックのどちらの表記もオペランドを1増分する。 それではなぜ 2 つの異なったバージョンがあるのか? それぞれの表記が異なった 値を評価するためである。op++ は増分演算を行う前にオペランドの値を評価し、 ++op は増分演算の後にオペランドの値を評価する。

例えば文字数を数えるプログラムで、countが 5 であるとき、次の文が実行されたとする。

count++;
 
文が実行された後、 count の値は6である。 しかし、 count++ 文それ自身の値は 5 である。 同じやり方で ++のプレフィックス表記を実行する。
++count;
 
同じく、 count に 6が設定される。しかし、文 ++ count 自身の値は ポストフィックス表記の5 で はなく、6 である。 この相違は文 字数を数えるプログラムで重要でないが、文の値を計算、フロー制御、あるいは何かのために使用している場合 には重要である。 制御フロー文でフロー制御の詳細 を学習する。

同様に、--++と同じようにプレフィックスとポストフィックス 表記を持っている。

Operator    Use
Description
   ++      op ++       Increments op by 1
   ++      ++ op       Increments op by 1
   --      op --       Decrements op by 1
   --      -- op       Decrements op by 1

関係演算子と条件演算子

関係演算子が 2 つの値を比較して、それらの関係を判定する。 例えば、 2 つのオペランド が等しくないならば、 != true を返す。 文字数を数えるプログラム では System.in.read() が返す値が - 1 と等しくないかどうかを判定するために、 != を使用する。

次の表は Java の関係演算子をまとめたものである。

Operator     Use          Returns true
if
   >      op1 > op2       op1 is greater than op2
   >=     op1 >= op2      op1 is greater than or equal to op2
   <      op1 < op2       op1 is less than to op2
   <=     op1 <= op2      op1 is less than or equal to op2
   ==     op1  == op2      op1 and op2 are equal
   !=     op1 != op2      op1 and op2 are not equal
より複雑な判定をする式を作成するために、しばしば関係演算子は条件演算子という別の演算子とともに 使用される。 そのような演算子の1つが、論理型と演算を行う&&である。 例えば、2つの 関係が true であるかどうかを判定するために、&&とともに2つの異なる関係演算子 を使用することができる。 次のコード行はこのテクニックを使用して、配列のインデックスが2つの 境界の間にあるかどうか、つまり、indexがゼロより大きくて NUM_ENTRIES (既に定義されている定数値である)よりも小さいかどうかを判定する。
0 < index && index < NUM_ENTRIES

3つの条件演算子がある。
Operator     Use          Returns true
if
   &&      op1 && op2     op1 and op2 are both true
   ||      op1 || op2     either op1 or op2 is true
   !       ! op           op is false
オペランドの両方が論理型であれば、演算子 &&& の同義語と して使用できる。 同様に、 もしそのオペランドの両方が論理型であるならば、 ||| の同義語である。

ビット単位の演算子

ビット演算子により、データのビット操作を行うことができる。 次の表は Java 言語で使用可能なビットおよび論理演算子である。
Operator     Use
Operation
   >>     op1 >> op2      shift bits of op1 right by distance op2
   <<     op1 << op2      shift bits of op1 left by distance op2
   >>>    op1 >>> op2     shift bits of op1 right by distance
op2 (unsigned)
   &      op1 & op2       bitwise and
   |      op1 | op2       bitwise or
   ^      op1 ^ op2       bitwise xor
   ‾      ‾ op            bitwise complement
3つのシフト演算子は、右辺のオペランドが示したビット数だけ、左辺のオペランドのビットをシフトする。 シフトは演算子それ自身によって示される方向で発生する。 例:
13 >> 1;

は、整数13のビットを右に1つシフトする。 13のバイナリ表現は1101である。 シフト操 作の結果は1101を1ビット右へシフトすると、110または10進で6となる。 一番右にあるビットが ビットの情報から落ちるので注意する。 右シフトは、左辺のオペランドを2つの右辺のオペランド乗で割ることと等しいが、右シフトの方がより効率的である。左シフトは、2のべき乗をかけることと等しい。

ビット単位の演算は、各オペランドの各ビットごとに対応した、「論理積」を実行する。 もし両方のオペランドが 1 であるなら、「論理積」は結果のビットを1に設定する。

op1    op2   result
 0      0      0
 0      1      0
 1      0      0
 1      1      1
値12 と 13 の「論理積」を考える。
12 & 13

この演算の結果は 12 である。 なぜか? 12 のバイナリ表現は 1100、13 のバイナリ表現は 1101 である。 両方のオペランドのビットが 1 であれば、「論理積」では結果のビットは1に 設定されるが、そうでなければ結果のビットは0になる。 2つのオペランドに対して「論理積 」を実行した場合、各オペランドの上位ビット2つ(各数の左側の2ビット)は1であり、 結果の値もまた1になる。 下位ビットはオペランドの片方のビットまたは両方のビットが0なので、0となる。
    1101
  & 1100

  ------
    1100
| 演算子は論理和演算を行い、^ は排他的論理和演算を行う。 論理和は、2 つのビットのどちらかが 1 であるなら 、結果は1であることを意味する。
op1    op2   result
 0      0      0
 0      1      1
 1      0      1
 1      1      1
排他的論理和は、2 つのオペランドのビットが異なっているなら、結果は1であり、そうでなけれ ば結果は0になることを意味する。
op1    op2   result
 0      0      0
 0      1      1
 1      0      1
 1      1      0

最後に、補数演算子はそれぞれのオペランドのビットの値を反転させる。つまり、オペランドのビットが 1 であるなら結果は0であり、オペランドビットが 0 であるなら結果は 1 である。
‾ 12

これは 3 になる(1100の補数は、0011である)。

特に、ビット単位の操作は、論理型のフラグの設定を管理するのに役立つ。 例え ば、さまざまなコンポーネントの状態(可視である、デバッグ可能など)を示すためにプログラムに、 いくつかの論理型のフラグがあると仮定する。 それぞれのフラグに状態を保持するために別々の論理型の 変数を定義するよりも、それらのすべてに対する1つの変数、 flags、で 定義することができる。 それぞれの flags 内のビットがフラグの1つの現在の状 態を表す。 各フラグを設定したり取得するには、ビット演算を使用する。

最初に、プログラムで種々のフラグを示す定数を設定する。 "オン" になるビットが別のフラグとオーバー ラップしていないことを保証するために、これらのフラグはそれぞれ異なる2のべき乗でなければならない。 さらに、変数 flags のビットが、各フラグの現在の状態によって設定されるように flags を定義する。 次のコードの例では flags を0に初期化しており、これは すべてのフラグが 偽である(ビットのいずれも 設定されない)ことを意味する。

final int VISIBLE = 1;
final int DRAGGABLE = 2;

int flags = 0;

"visible" フラグを設定するためには、何かが可視になった時、次の文を使用する。
flags = flags ^ VISIBLE;

可視性のテストを行うためには、次のように書く。
flags & VISIBLE

代入演算子

ある値を別の値に代入するために、代入演算子 を使用する。 文字数を数えるプログラムでは次の文で count を初期化するために を使用している。
**********
int count = 0 ;
基本的な代入演算子に加えて、 Java はショートカット代入演算子を提供する。これを使用すること により、1つの演算子で算術、論理、ビット単位の演算や代入演算などすべての演算機能を実行するこ とができる。 次のような変数に数を足して、その結果を変数に代入することを考える。
i = i + 2;

ショートカット演算子 += を使用して、この文を短くすることができる。
i += 2;

上記の2つのコードは等しい。

次は、ショートカット代入演算子とそれらと同等の式の一覧である。

Operator     Use          Equivalent
to
   +=      op1 += op2     op1 = op1 + op2
   -=      op1 -= op2     op1 = op1 - op2
   *=      op1 *= op2     op1 = op1 * op2
   /=      op1 /= op2     op1 = op1 / op2
   %=      op1 %= op2     op1 = op1 % op2

   &=      op1 &= op2     op1 = op1 & op2
   |=      op1 |= op2     op1 = op1 | op2
   ^=      op1 ^= op2     op1 = op1 ^ op2
   <<=     op1 <<= op2    op1 = op1 << op2
   >>=     op1 >>= op2    op1 = op1 >> op2
   >>>=    op1 >>>= op2   op1 = op1 >>> op2


Previous | Next | Trail Map | Writing Java Programs | Java 言語のナットとボルト