【Javaプログラミング超入門 #07】演算子

 

みのる
こんにちは。笑顔で感謝!✨ みのるコーチです。
今回も、ご覧いただき、ありがとうございます。

今回は

Java超入門 #7
Java の 演算子

というテーマでお送りします。

彩香
Java が段々と 分かってきました。
今回も、よろしくお願いします。
剛留
「演算子」って計算だから、足し算とか引き算とか分かりますが…。
その他に、どんな「演算子」があるか楽しみです。
みのる
それでは 早速 行ってみましょう。

【Youtube版】

Youtubeでもお伝えしていますので
是非チェックしてくださいね。

【1】 式

①式とは

式とは
✅ Javaの文(ステートメント)のうち
  演算を行うもの。
✅ 式は「オペランド」と「演算子」で
  構成されている。

今まで出てきた例を見てみましょう。

式1) age = 24 ;
式2) nextAge = age + 1;
式3) intro = “来年は” + nextAge + “歳” ;

このようなプログラムを見た時に

式1では、オペランドは age と 24、演算子は = です。

式2では、オペランドが nextAge と age と 1
演算子は、= と + です。

式3では、オペランドが intro “来年は” nextAge “歳”、
演算子 が、= と + と + です。

こうして見ると

オペランドは 値を持つもの。
演算子は「加工する」「仕事する」もの。

と言えますね。

彩香
オペランドは 値を持つもので、演算子は加工する役割をもつもの。
ノートしておきました。
剛留
完璧です!

②オペランド

オペランド
・オペランドになるのは
 ❶リテラル
 ❷変数
 ❸定数
 ❹処理の結果

❶~❸については、今まで学んできましたね。

❶ リテラルは、プログラムの中に直接記述される値。
❷ 変数は、値を格納する箱。
❸ 定数は、値を1度だけ格納できる箱。

…という意味でした。

忘れてしまったかたは、#05 変数・#06 データ型
見返してみてくださいね…。

【Javaプログラミング超入門 #05】変数

【Javaプログラミング超入門 #06】データ型

そして、❹ については、少し先で メソッドについて
学ぶ時に説明します。

ですので、今回は、オペランドについて
❶ ~ ❸ で考えましょう。

③評価

もう一つ「評価」について、知っておきましょう。

式は、演算子ごとに段階的に評価されて
最終的に式が評価されます。

ここでいう評価は「加工した結果を出す」という感じで
イメージしておきましょう。

彩香
ん~。ちょっと難しくなってきましたね~。
みのる
こんな例を考えてみましょう。
a = 3 + 5 – 2;

ここでは、代入演算子は最後と考えて頂いて…。

まずは、3+5の演算が行われます。
この演算を行うことを 「 評価 」 と呼びます。

結果は8ですね。この8が評価の結果です。

すると、3+5の部分は8に置き換わります。

a = 8 – 2;

そして、8 – 2 ですが、- マイナスは引き算の意味で
評価されると 6 になります。

a = 6;

そして、最後に代入演算子です。

これは右辺から左辺に値を代入するという意味で
a には 6 が代入されます。

そして、この式の評価結果は 6 になります。

彩香
そういう事なんですね。理解できました。

【2】演算子

ここでは、演算子の種類について お話します。
この 6 つの分類について 順に見ていきましょう。

①連結演算子

連結演算子は + プラスの記号を使います。
左辺または右辺が 文字列の場合に オペランドを連結します。

この時、文字列でないオペランドは
自動的に文字列に 変換されます。

例えば、この例の下側ですが、文字列 + 整数リテラルです。

この場合には、24 は自動的に文字列に変換されて
評価結果は “年齢:24” となります。

②算術演算子

算術演算子を見ていきましょう。

まず、+ プラス は加算 – マイナス は減算です。
これは 算数の 足し算 と 引き算 と同じです。

* アスタリスク は乗算(掛け算)です。
この掛け算の記号にも慣れていきましょうね。

除算については「商」を求める演算子と
「余り」を求める演算子があります。

例えば 5 ÷ 2 は「商」が 2 「余り」が 1 ですが…

商を表す演算子は / スラッシュです。
そして、余りを表す演算子は % です。

ここでは、この * / % という演算子のを初めて見る
かも知れませんので、意味を押さえておきましょうね。

剛留
算術演算子 と 連結演算子 を使ってプログラムを
書いたんですが、結果が変なんです…。
class Sample {
    public static void main(String[] args) {
        int age = 24;
        System.out.println(“来年は” + age + 1 + “歳です”);
    }
}
剛留
まず、age に 24 を代入して。
来年の年齢を表示しようと思ったんです。25歳です。

そうしたら…。
「 来年は241歳です 」と表示されちゃったんです。

彩香
剛留くん、241歳になっちゃうの?
急に、ヨボヨボの、おじいさんになるの?

剛留
そんな訳、ないでしょ。

…っていうか、241歳って、完全に
お亡くなりになってるでしょ…。

もう、勘弁してくださいよ。

みのる
剛留くん、色々と試してみているのは良い事ですね。
Nice Try !

そして、ソースプログラムを見ていくと…。

int age = 24;
System.out.println(“来年は” + age + 1 + “歳です”);

この、System.out.println は () の中を表示しますが
…この中に4つのオペランドと3つの演算子がありますね。

すべて + の演算子で、この場合には
左側から順に評価していきます。

最初に、一番左の演算子を考えてみると、左辺が文字列なので
連結演算子で連結されて、文字列 “来年は24″になります。

次に、評価された文字列と、1 が連結演算子で連結されて
“来年は241″になります。

そして最後に、この文字列と “歳です” が連結されて
“来年は241歳です”に、なってしまうのです。

やりたかった事は、age + 1 の部分が先に評価される事ですね。

このような時には、() 丸括弧で囲むと
Javaが優先して評価してくれることになるんです。

そうすれば、この + は左辺も右辺も数値なので…

算術演算子(加算)と解釈して
この部分の評価は 25 になります。

int age = 24;
System.out.println(“来年は” + ( age + 1 ) + “歳です”);

このように、修正すれば、大丈夫ですよ。

剛留
できました!
無事に、来年25歳になれます!
みのる
良かったです。この () 丸括弧で優先的に評価することは
利用する事が多くなると思いますので、覚えておきましょうね。

③インクリメント演算子/デクリメント演算子

インクリメント演算子・デクリメント演算子について
見ていきましょう。

まず、変数に1を足したい場合に使用するのが
インクリメント演算子です。++(プラスプラス)の記号を使います。

オペランドは 1つだけで、この演算子を
後につける場合(後置)と前につける場合(前置)があります。

後置の場合には、式の中で元の値を評価した後に1が足されます。

前置の場合には、式の中で元の値に1が足された後に評価します。

以下の【式1】・【式2】を考えてみましょう。

【式1】

(a が 10 の場合)

b = a++; // 【結果】bの値は 10、aの値は 11

【式2】

(a が 10 の場合)

b = ++a; // 【結果】bの値は 11、aの値は 11

例えば、int型の変数 a の値が 10 の場合を 考えましょう。

式1の右辺 a++ は まず a が評価されて 10 。
その後に a に 1が足されます。つまり a は 11 になります。

そして、b には 右辺の評価結果の 10 が代入されて
b の値は 10 になります。

結果、bの値は 10 、aの値は 11 です。

式2は、まず a に 1 が足されて 11 になります。
その後に評価されるので、右辺の評価結果は 11 になります。

そして、b には 右辺の評価結果の 11 が代入されて
b の値は 11 になります。

結果、bの値は 11 、aの値は 11 です。

また、変数から1を引きたい場合に使用するのが
デクリメント演算子です。–(マイナスマイナス)の記号を使います。

こちらも オペランドは 1つだけで、この演算子を
後につける場合(後置)と前につける場合(前置)があります。

後置の場合には、式の中で元の値を評価した後に1を引きます。

前置の場合には、式の中で元の値から1を引いた後に評価します。

この考えは、インクリメント演算子の場合と同様です。

④関係演算子

関係演算子は、2つのオペランドの関係を判定して
結果は boolean型 で true または false で評価されます。

まず < 小なり記号の演算子です。

左辺と右辺を比較して、左辺が小さい時に true
そうでない時に false となります。

例を見ると a < b これは、a の値が b の値より小さければ true
そうでなければ false になります。

視覚的に、分かりやすいですよね。

次に > 大なり記号 の演算子です。

こちらは、左辺が大きい時に true そうでない時に false です。

こちらの例 a > b は、a のほうが大きければ true になります。
こちらも、直感的に 理解できそうですね。

次は、2文字の演算子 <= 小なりイコールです。
これは 左辺が小さい または左辺と右辺が等しい時に true です。

次が >= 大なりイコール。
こちらは、左辺が大きい または左辺と右辺が等しい時に true です。

そして、次です。

== (イコールイコール) という演算子です。

これは、左辺と右辺が等しい時に true になります。
代入演算子の = と間違えやすいので、注意が必要です。

== は関係演算子で比較ということ、覚えておきましょうね。

最後が != と書く演算子です。

ノットイコールと読む事が多いですが…

これは 左辺と右辺が等しくない時に true になります。

何となくの ! エクスクラメーションマークで
「違うでしょ」と言われているイメージですかね…。

こちらも、特徴的な記号の並びですね。

彩香
関係演算子 を使ってみたんですが
コンパイルで エラー になってしまうんです…。
class Sample {
    public static void main(String[] args) {
        int age = 26;

        boolean result = ( 20 <= age < 30 );
        System.out.println(“20代:” + result);
    }
}

これをコンパイルしたら、エラーが出てしまって…。

二項演算子'<‘のオペランド型が不正です
最初の型: boolean
2番目の型: int

と出てしまって…。

剛留
age が 20歳以上で 30歳未満だったら…

result に true が代入されて
20代:true と表示されるってことですね…。

どこが ダメなんだろう…?

みのる
彩香さんも、プログラムを色々と試しているんですね。
とっても良い感じです、Nice Try! です。

そして、プログラムを見ていくと…。

20 <= age < 30

この部分で、2つの関係演算子がありますね。

この場合も、左から順に評価す事になります。
まず、20 <= age の部分は true になります。

そして、次に、評価結果の true と 30 を比較して

true < 30

を評価する事になります。

しかし、この場合、左辺は boolean型で右辺が int型なので
大小比較ができない事になってしまうのです。

それで、エラーメッセージ

二項演算子'<‘のオペランド型が不正です
最初の型: boolean
2番目の型: int

となってしまうんです。

20 <= age < 30

ここで、やりたいことは…。

「 age が 20 以上 」 かつ 「 age が 30 未満 」
という事ですね。

これは、次の「論理演算子」を理解すると
できると思います。

解説を聴いてみましょうか…。

彩香
はい 「全集中!」で 聴きます。

⑤論理演算子

論理演算子は、その名の通り オペランドは論理型限定です。

まず、&& 記号です。
これは、左辺と右辺が共に true の時 true となります。

論理積 とか 論理AND という言い方をします。

例を見てみましょう。

(age >= 20) && isMan です。

ここで、age は年齢を表す int 型の変数
isMan は boolean型で 男性の場合 true の値を持つ変数です。

この場合には、ageが 20 以上 が true で isMan も true の場合に
true となります。

次が縦線2つの演算子です。
この縦線の記号は、バーティカルバーとかパイプと呼びます。

この演算子は、左辺と右辺の少なくとも一方が trueの時に
trueとなります。

論理和 とか 論理OR と言います。

こちらも例を見てみましょう。

(age >= 20) || isMan

(age >= 20) か isMan の少なくとも一方が true の時に true です。

true – trueの場合、true – falseの場合、
false – trueの場合があります。

次が ! エクスクラメーションマークです。

論理否定 論理NOT と言います。

こちらはオペランドは1つだけです。
この例のように、オペランドの左側に!をつけて表します。

この場合 (age >= 20) が true であれば falseになり
(age >= 20) が false であれば trueになります。

この演算子は、少し複雑な論理演算を行った場合に
全体を否定する場合などに 使われることがあります。

彩香
はい、さっきのプログラムの修正できました。
思い通りに動きました。見てください。
class Sample {
    public static void main(String[] args) {
        int age = 26;

        // boolean result = ( 20 <= age < 30 );
        boolean result = ( 20 <= age ) && ( age < 30 );
        System.out.println(“20代:” + result);
    }
}

みのる
はい「全集中」で聴いた甲斐がありましたね!
素晴らしいです。
彩香
やった~。

⑥代入演算子

代入演算子を見ていきましょう。

まず = です。これは、今まで出てきていますので
大丈夫と思いますが 改めて確認しておきましょうね。

右辺の値を 左辺に代入する という意味です。
右から左 と覚えておきましょうね。

次が += です。これは、左辺と右辺を足し算して
結果を左辺に代入する という事になります。

ただし

左辺が文字列型の場合には
左辺と右辺を連結して 左辺に代入する

事となります。

例を見ると、a += b; と書くと a = a + b; と
書いた事と同じになります。

+= のほうが、少しスッキリしていますかね。
足し込んでいる事が 分かりやすいとも言えますね。

-= は、左辺から右辺を引いた値を左辺に代入します。

*= は、左辺と右辺を掛けた値を左辺に代入します。

そして /= は、左辺を右辺で割った商を左辺に代入します。

同様に %= は、左辺を右辺で割った余りを左辺に代入します。

この下5個を合わせて複合代入演算子といいます。
左辺と右辺の演算を行って、左辺に代入します。

そして、評価の結果は 左辺に代入した値 になります。

演算結果は左辺に代入して、同時に評価の結果になります。
イメージを掴んでおきましょうね。

【3】規則

① 優先順位と結合規則

これまで、演算子について見てきましたが、式の中で複数の演算子が
使われた場合に どの順で評価されるかを 考えていきましょう。

この場合には「優先順位」と「結合規則」に従って
評価の順は決定されることになります。

本日お話した演算子について まとめてみました。

Javaでは、この表の上が優先順位が高いと
定められています。

また同じ優先順位の場合に、左側から・右側から
どちらから評価されていくかも定められています。

この左側・右側からという事を結合規則といいます。

大枠で見ておきましょう。

優先順位が高いのは、インクリメント・デクリメント演算子と
論理否定といった、1つのオペランドに対応する演算子です。

単項演算子といいますが、まずは優先度が高いです。

次に優先順位が高いのが、算術演算子と文字列連結です。

この中では、乗算・除算・剰余が高く
加算・減算・文字列連結が低いこととなります。

その下が、関係演算子になります。

この中では大小判定が優先度が高く
同値判定が優先度が低くなっています。

次が論理演算子のうち左辺・右辺を持つ演算子です。
論理AND が優先され、論理ORは優先度が低くなっています。

一番 優先順位が低いのが、代入演算子・複合代入演算子です。

今まで、最後に代入されます…、と説明していた部分ですが
明確に 優先順位が低いと定められているのですね…。

そして、結合規則については、左辺・右辺を持つ演算子について
順番を考える場合が多いと思います。

この中では、基本的には左から右と考えて頂いて大丈夫です。

そして、これだけ
代入演算子・複合代入演算子については、右から左です。

優先順位と結合規則については、ガッツリ全部を覚えようと
しなくて大丈夫です。

この一覧を参照しながら書ければ大丈夫ですし
数を多くこなして行くと、自然と慣れてくるものなのです。

②わかりやすさ優先

優先順位と結合規則について 見てきましたが…

プログラムを書く時には、わかりやすさを優先して
書く事を心がけましょう。

この時に、この2つを考えていくと良いですね。

❶ ( ) 括弧をつける

例えば、このような場合を 考えてみましょう…。

int a = 5;
int b = 2;
int c = 2;
int d = 3;
int e = 3;

boolean r = a + b * c == d * e;

これは * の優先順位が高いですね。
b * c は 4 、d * e は 9 になります。

その次が + ですね。
ですので a + 4 で 9 になります。

そして 同値判定の == ですね。
9 と 9 を比較して true になります。

そして、最後に = 代入演算子で
r に true が代入されます。

ただし、このようなプログラムは、後から読んだ時に
わかりにくいプログラムになってしまいます。

この場合、わかりやすさを考えて、この1行は
次のように書くほうが望ましいと言えます。

boolean r = ((a + (b * c)) == (d * e));

この場合には、丸括弧がなくても同じ動きですが
丸括弧があると、人に優しい感じがします…。

❷行を分ける

別の例を見てみましょう…。

int a = 10;
int b = 3;
int c;

c = a += b++;

この最後の1行は
少し読みづらいように思います。

この1行は、行を分けて
次のようにも書くことができます。

a += b;
c = a;
b++;

これに合わせて、意味あいなどを分かりやすく
コメントで書いておくと良いですね。

易しさが、優しさに繋がると、私は思っています。

彩香
見て わかりやすいプログラムを 心がけます。
剛留
優先順位と結合規則は、大切ですね。
最初は、表を見ながら慣れていきます!

【まとめ】

【1】式
①式とは

・文のうち演算を行うもの。
・「オペランド」「演算子」で構成。
・オペランドは 値を持つ もの。
・ 演算子は 加工する もの。

②オペランド

 ❶リテラル
 ❷変数
 ❸定数
 ❹処理の結果

 ※今回は❶~❸を見てきました。 

③ 評価

・ 評価は、演算子がオペランドを
  加工して結果を出すこと。
・ 優先順位・結合規則に従って
  段階的に評価する。

【2】演算子
① 連結演算子
② 算術演算子
③ インクリメント演算子
  デクリメント演算子
④ 関係演算子
⑤ 論理演算子
⑥ 代入演算子
【3】規則
① 優先順位と結合規則

・ まず優先順位の高い順に評価する。
・ 同じ優先順位の場合には
  結合規則に従う。
  (右から・左からという方向)

② わかりやすさ優先

・わかりやすさ優先で、以下を考える。

 ❶ ( ) 丸括弧をつける
 ❷ 行を分ける