演算子の優先順位 - 1

「こんにちは、ビラーボ!」

「ビラーボは友達に喜んで挨拶しています!」

「今日、Bilaabo は演算子の優先順位について説明します。しかしその前に、演算子自体について説明します。」

「あなたが話している演算子とは何ですか?」

「実のところ、あなたはすでにそれらのことをよく知っています。単にオペレーターと呼ばれていることを知らなかっただけかもしれません。」

"たとえば、  c = a + b;という式があるとします。"

「加算演算子と代入演算子の 2 つの演算子があります。」

「つまり、演算子は単なる数学記号ですか? 乗算、除算、加算のようなものですか?」

「はい、その通りです。しかし、違いもあります。」

「私は演算子を定義しません。定義したからといって賢くなるわけではありません。実際に演算子が動いているのを見るほうが良いでしょう。演算子はいくつかのグループに分類できます。これから検討していきます。」

1)数学演算子

シンボル 名前 説明(何をするのか)
+ a + b 加算演算子 加算演算子。
- c - d 減算演算子 最初の数値から 2 番目の数値を減算します。
* a * t 乗算演算子 2 つの数値を乗算します。
/ a / b 除算演算子 最初の数値を 2 番目の数値で除算します。
% c % d 最初の数値を 2 番目の数値で除算します。 最初の数値を 2 番目の数値で割った余りを計算します。
- -a 単項マイナス 変数の符号を反対に変更します。
プラスからマイナス、マイナスからプラス。
+ +a 単項プラス 何も変わりません。これは、単項マイナス演算子を補完するために追加されました。それはただ見た目のためです。

「学校で教えてもらったものだと認識しています。私のファームウェアには学校のコースが含まれています。」

「しかし、そのパーセント記号は何ですか、ある種の魔法ですか?」

「これは、「除算後の剰余」演算子です。11 を 5 で割ると、2 が得られ、剰余は 1 になります。この 1 は、11 % 5; と書くことで取得できます。」

「Java で整数を除算すると、結果も整数になります。除算演算の余りは単純に無視されます。8 を 5 で割ると、1 が得られます。」

表現 結果
19 / 10 1 19 を 10 で割ると、結果は1 になり、余りは 9 になります。
19 % 10 9 19 を 10 で割ると、結果は 1 になり、余りは9 になります。
2 / 5 0 2 を 5 で割ると、 結果は0 になり、余りは 2 になります。
16 % 2 0 16 を 2 で割ると、結果は 8 になり、余りは0 になります。

「しかし、残りはいったい何に必要なのでしょうか?」

「整数が偶数かどうかをチェックする必要があるとします。その場合は次のように書くことができます。」

if (a % 2 == 0)

「そして、b が奇数かどうかを確認する必要がある場合は、次のように書くことができます。」

if (b % 2 == 1)

「または、d が 3 で割り切れるかどうかを確認するには:」

if (d % 3 == 0)

「面白いですね。覚えておきます。」

2) 比較演算子

シンボル 名前 説明(何をするのか)
< a < b 未満 a が b より小さいかどうかを確認します。
<= c <= d 以下 c が d 以下かどうかを確認します。
> a > b より大きい a が b より大きいかどうかを確認します。
>= c >= d 以上 c が d 以上であるかどうかを確認します。
== i == j 等しい i が j に等しいかどうかを確認します。
!= a != 0 等しくありません a がゼロに等しくないかどうかを確認します。

「これらはすべてすでに使用しています。」

「そして、これらの演算子と数学演算子の主な違いは何ですか?」

「2 つの数値を加算すると数値が得られますが、2 つの数値を比較すると真か偽が得られます。」

「そうです。比較の結果は「論理値」値です。ご存知のとおり、これはブール型で表されます。true または false の 2 つの可能性があります。

「はい、それは明らかです。私はすでにそれを知っています。」

3)論理演算子

シンボル 名前 説明(何をするのか)
&& a && b 式の結果は、a と b の両方が true の場合にのみ true になります。
|| c || d また a または b のいずれかが true の場合、式の結果は true になります。両方、または少なくとも 1 つ。
! !a いいえ 式の結果は、a が false の場合にのみ true になります。

「論理演算子はブール変数または式でのみ使用できます。」

説明
boolean a = true;
boolean b = true;if (a && b)
if 条件は、両方の値が true の場合に true になります
。つまり、a と b の両方がtrue の場合、結果はtrueになります。
boolean a = true;
boolean b = false;if (a || b)
if 条件は、少なくとも 1 つの値が true の場合に true になります
。つまり、a または b のいずれかが true の場合、結果はtrueになります。
boolean b = false;

if (!b)

b が true でない場合、if 条件は true になります。
つまり、   b が false の場合、結果は trueになります。
int a = 2, b = 3, c = 4;

if (a < b && a < c)
if ((a < b) && (a < c))

a が b より小さく、a が c より小さい場合、式の結果は true になります。
a、b、c は整数ですが、整数を比較した結果は論理値 (true、false) になるため、論理演算子を使用できます。

「私はすでにすべてを知っています。」

「そうですか?それでは続けましょう。」

4)ビット演算子

シンボル 名前 説明(何をするのか)
& a & b ビットごとの AND
| c | d また ビットごとの OR
~ ~a いいえ ビットごとの NOT
^ a ^ b XOR ビットごとの「排他的論理和」

"ビット演算子は、整数に対してビットごとの演算を実行します。"

"あれは何でしょう?"

「各数値はビットのセットとして表され、結果は次のように計算されます。」

「両方の数値の最初のビットが 1 の場合、結果の最初のビットは 1 になります。」

「両方の数値の 2 番目のビットが 1 の場合、結果の 2 番目のビットは 1 になります。以下同様です。」

「それはすべてのビット演算子に当てはまりますか?」

「それよりもずっと簡単です。ビットは 0 と 1 の 2 つの値しか持てませんよね?」

"右。"

「次に、1 を true、0 を false と考えてください。個々のビットに対する演算は、論理演算とほぼ同じになります。」

論理式 ビット単位の式
true && true == true 1&1 == 1
true && false == false 1&0 == 0
本当 || true == true 1|1 == 1
本当 || false == true 1|0 == 1
偽 || 偽 = 偽 0|0 == 0
!false == true ~0 == 1
!true == false ~1 == 0

「ああ!それはとても簡単です。」

「はい、ビット単位の演算では 2 つの数値の対応するビットが使用されることを忘れないでください。」

「はい、覚えています。ある数値の最初のビットは 2 番目の数値の最初のビットとペアになっていて、結果も最初のビットに書き込まれます。残りのビットにも同じことが当てはまります。」

「そうです。他に質問はありますか?」

「XOR と '排他的論理和' とは何ですか?」

「それは簡単です。値が異なる場合は true、同じ場合は false です。」

論理式 ビット単位の式
true XOR true == false 1 ^ 1 == 0
false XOR false == false 0 ^ 0 == 0
true XOR false == true 1 ^ 0 == 1
false XOR true == true 0 ^ 1 == 1

ビット単位の演算の例をさらにいくつか示します。

ビットとしての数値 ビットとしての結果 結果
5 & 3 0000010 1  & 0000001 1 0000000 1 1
7 & 2 000001 1 1 & 000000 1 0 00000010 2
5 | 9 00000 1 0 1  | 0000 1 00 1 00001101 13
5 ^ 9 00000 101  ^ 00001001 0000 1100 12
~9 00001001 11110110 246

「ありがとう、ビラーボ。もうわかった。」

「ビット演算子のグループがもう 1 つあり、シフト演算子です。」

5)シフト演算子

シンボル 名前 説明(何をするのか)
>> a >> b 右シフト 数値 a のビットを右に b 桁シフトします。
<< c << d 左方移動 数値 c のビットを d 桁左にシフトします。
>>> a >>> 2 符号なし右シフト 数値 a のビットを右に 2 桁シフトします。

「これはどんなストリートマジックですか?」

「実はどれもとても簡単です。ぜひチェックしてみてください。」

ビットとしての数値 ビットとしての結果 結果
10 >> 1 0000 101 0 >> 1 00000 101 5
10 >> 2 0000 101 0 >> 2 000000 10 2
10 << 1 0000 101 0 << 1 000 101 00 20
10 << 2 0000 101 0 << 2 00 101 000 40

「数値のビットを左に 1 シフトすることは、数値を 2 倍することと同じです。2 桁シフトすることは、4 桁の乗算、3 桁の乗算、つまり 8 の乗算などと同等です。」

「右へのシフトは、2、4、8、16 などによる除算に対応します。」

「しかし、>>> 演算子と >> 演算子の違いは何ですか?」

「負の数値を扱う場合、それらは異なります。これは、 符号付き数値では、符号を示すために左端のビットが使用されるためです。その結果、負の数値は、右にシフトすると負ではなくなります。そこで、彼らは 2 つの異なる演算子を考え出しました。見てみな:"

表現 結果 説明
1 000 1010 >> 1 11 000 101 負の数は負のままです。
負の数の場合、受信ビットは 1 で埋められます。
1 000 1010 >> 2 111,000 10 _
1 000 1010 >> 3 1111 000 1
1 000 1010 >>> 1 01 000 101 負の数は負ではなくなりました。負の数の場合、受信ビットは 0 で埋められます。
1 000 1010 >>> 2 001 000 10
1 000 1010 >>> 3 0001 000 1

「シフトは循環的ではありません。数値の左端または右端を越えて移動するビットは単純に破棄されます。」

6)代入演算子

「割り当てが何であるかはすでに知っています。しかし、なぜ『演算子』というのでしょうか?」

「何個かあるから☺」

オペレーター その意味
a += b; a = a + b;
a -= b; a = a - b;
a *= b; a = a * b;
a %= b; a = a % b;
a |= b; a = a | b;
a &= b; a = a & b;

「論理は理解できたと思います。」

7)インクリメント演算子とデクリメント演算子

表記 説明
++ a++;
++b;
数値を 1 増やします。
-- d--;
--i;
数値または変数を 1 減らします。

「2 つのマイナス記号を変数の前に置くか後ろに置くかに違いはありますか?」

「はい、ありますが、それほど大きくはありません。これらの演算子のいずれかを含む変数が式または代入の一部である場合、違いがあります。むしろ例で示したいと思います。」

本当に何が起こるのか 説明
int a = 3;
int b = ++a;
int a = 3;
a = a + 1;
int b = a;
a は最初に 1 だけ増加されてから、式で使用されます。
int a = 3;
int b = a++;
int a = 3;
int b = a;
a = a + 1;
a は最初に式で使用され、その後 1 ずつ増加します。
int a = 3;
return a++;
int a = 3;
int result = a;
a = a + 1;
return result;
関数は 3 を返しますが、a の値は 1 ずつ増加します。
int x = 5;
x = ++x + ++x;
int x = 5;
int a = x + 1;// The first term is 6
x = a;
int b = x + 1;// The second term is 7
x = b;
x = a + b;
ここでの結果は 13 です。まず、x が 1 ずつ増加し、この値が最初の項を置き換えます。その後、x は再び 1 ずつ増加します。

「おお!カッコいいですね!」

「気に入っていただけてうれしいです。ただし、式や割り当てがない場合は、違いはありません。」

「x++ は x = x + 1 と同等です。」

「++x は x = x + 1 と同等です。」

「覚えておきます。ありがとう、ビラーボ。」

8)  「三項演算子

「この演算子は、1 つまたは 2 つの変数または式を使用するだけではありません。3 つの変数または式を一度に使用します。」

表記 同等のコード:
a ? b : c; if (a)
b
else
c
int min = a < b ? a : b; if (a < b)
min = a;
else
min = b;
return a != null ? a.length : 0; if (a != null)
return a.length;
else
return 0;

「なるほど、それはとても便利ですね。」

「はい。コンパクトでコードも読みやすいです。楽しんで使ってください!」

9)その他

「音楽コレクションがどれだけ整理されていても、「その他」フォルダーを作成する必要があります。」

「そうだ、音楽を分類しなければならなかった人なら誰でも完全に同意するだろう。」

「それで、さらに 3 つの演算子についてお話したいと思います。」

表記 説明
() (a + b) * c 括弧を使用すると演算子の優先順位が高くなります。
括弧内のものが最初に実行されます。
[] c [i] = c [i + 1]; インデックスによって配列要素を取得します。
. int n = a.length; ドット演算子」はオブジェクトの変数とメソッドにアクセスします。

「そして最後に、演算子の優先順位をまとめた表を以下に示します。」

オペレーター
最も高い優先順位 (演算子はこの表の順序に従って実行されます)
()
[]
.
(a + b)
c [i] = c [i] + 1
++
--
~
!
+
-
i++; ++i;
--j; a--;
~c
!f
return +a;
return -a;
*
/
%
a * b
c / d
a % b
+
-
a + b
c - d
String s = "count"+"35";
>>
<<
>>>
a >> 3
b << 2
c >>> 3
<
<=
>
>=
a < b
a <= b
c > b
c >= b
==
!=
a == 3
a != 0
& a & 7
^ a ^ b
| a | b
&& (a < b) && (a < c)
|| (b != 0) || (c != 0)
? : = a > 0 ? a : -a;
=
*=, /=, %=
-=, +=
<<=. >>=, >>>=
&=, ^=. |=
最も低い優先順位 (最後に実行される)