Transcript Ch04

Ch04 運算子
JAVA程式語言入門(I)
授課教師:王大瑾
運算式
• 運算子:程式中用以運算的符號
• 運算元:被運算的常數或變數
• 運算式:運算子和運算元組成用以運
算的式子
• 常見的運算式:
a+1
7+8
5+9*3-b
x=6
2
運算式
運算式的結果也是一個值,所以運算
式可以視為另一個運算式的運算元
運算式
c = c + 1
子運算式
3
敘述
運算式後面加一個分號(;),運算式可以
被提升變成一個敘述(statemant)
c = c+1;
不是每個運算式都可以加上分號而變成敘述
c+1;
//錯誤
常見的合法敘述:
int n;
return 12;
n=12*a;
System.out.println(n);
//宣告變數
//方法中回傳數值
//將運算結果存至變數內
//呼叫方法
4
指定運算子
• 指定運算子的用法:
– 設定常數值給變數
a = 9;
– 將變數的內容指定給另一個變數
a = b;
– 將運算式的結果指定給變數
a = b+7*5;
5
指定運算子
• 「=」的左邊一定是變數,不能是數值。
• 結合性是由右至左。
• 多重指定的例子:
a
=
b = c
=
d = 5;
6
算術運算子
• 算術運算子的結合性是由左至右
• 優先序為:先(*/%)後(+-)
• 注意「運算時,型別的自動轉換」
運算子
+
*
/
%
語法
a
a
a
a
a
+
–
*
/
%
b
b
b
b
b
說明
a=5, b=2的
運算結果
a加b
a減b
a乘b
a除以b
a除以b的餘數
7
3
10
2.5
1
7
練習一
預測下列程式碼的輸出結果, 修正程式碼以
得到正確值
public class Ex03_01
{
public static void main (String arg [])
{
float c = 5 / 2;
System.out.println("int / int : c = "+c);
}
}
8
練習二
試寫一個程式:將一個十進制57轉換為二
進制111001
(提示一:可以不需要用判斷敘述及迴圈,
用較原始的方式處理,即某些敘述重覆六
次)
(提示二:利用除及餘數)
9
遞增、遞減運算子
a=a+1 → a++
b=b-1 → b--
不指定給其它變數,則兩種方式是相同的
a++
++a
若指定給另一個變數時,兩種方式的意義不同
c = ++a;
c = a++;
// 先將a加一後,再將a的內容指定給c
// 先將a的內容指定給c,a再加一
b = a++ + 5
可視為:
b = a + 5;
a++
10
算術指定運算子
算術指定運算子為二元運算子
結合性是由右至左
a=a+2
a=a+3
→
→
a+=2
a+=3
•各種算術指定運算子
算術指定運算子
一般算術式
簡化後的運算式
+=
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
11
關係運算子
• 布林值之間的關係運算只能使用 ==和 !=
兩個運算子,其餘的關係運算子都不能使用
關係運算子
>
說明
是否大於
範例
5>2
範例結果
true
>=
<
<=
==
是否大於等於
是否小於
是否小於等於
是否等於
5 >= 2
5<2
5 <= 2
5 == 2
true
false
false
false
!=
是否不等於
5 != 2
true
12
關係運算子
• 關係運算子的運算優先順序較算術運算子低
• 運算優先序:先(><>=<=)後(==!
=)
• 關係運算子結合性皆為由左至右
• 布林值之間的關係運算只能使用==和
!=兩個運算子,其餘的關係運算子都不能使用
13
範例1:Ch03_01.java
System.out.println( 3 > 7 == 1 >= 8 );
System.out.println( 3 >= 2.9 );
System.out.println( true == false );
boolean a=false;
boolean b=false;
System.out.println( a == b == false );
float f = 2E17F;
System.out.println( f == 2E17 ); //精確度問題
System.out.println(2E17f);
System.out.println(2E17);
14
練習三
執行下列程式碼,並探究為何有如此的輸出結果:
public class Ex03_03
{
public static void main(String arg [])
{
boolean a = true, b = false;
System.out.println(b == a);
System.out.println(b = a);
}
}
15
練習四
攝氏溫度(C)轉換為華氏溫度(F)的公
式為F=9/5*C+32
請撰寫一程式,可以將攝氏溫度0,54,
和98度輸出為華氏溫度
16
條件運算子
• ?: 是唯一的三元運算子,其語法如下:
判斷值 ? 真時選擇值 : 假時選擇值
• 常用的方式:
變數 = 判斷值 ? 真時選擇值 : 假時選擇值;
• 真時選擇值和假時選擇值的型別應該相
同,或是兩者都可以自動型別轉換指定
給變數。
ifPass = score>=60 ? ’Y’ : ’N’;
17
範例2:Ch03_02.java
class Ch03_02
{ public static void main(String [] args)
{ char level = 85;
//設定某科成績, 分數為何不用int資料型態
System.out.println( level>=60 ?
"過了,恭喜!" : "沒過,要加油囉!" );
level = level<60 ? '丁' : level;
level = level<70 ? '丙' : level;
level = level<80 ? '乙' : level;
level = level<90 ? '甲' : level;
level = level<101 ? '優' : level;
System.out.println("你得到:"+level);
}
}
18
練習五
將上一頁程式中的部份程式碼順序作更動
如下,是否仍然可以得到相同結果?
Level = level<101 ? ‘優' : level;
level = level<90 ? ‘甲' : level;
level = level<80 ? '乙' : level;
level = level<70 ? ‘丙' : level;
level = level<60 ? ‘丁' : level;
System.out.println("你得到:"+level);
(由於可能要用到 “且” 所以留到p.26再做)
19
練習六
將五個數值23, 45, 43, 21, 67依序設定給變數
a1, a2, a3, a4,a5.
1. 將a1的值給a2, a2給a3, a3給a4, a4給a5,
a5給a1
2. 找出五個數中最大值及最小值(用最少個
程式碼)
20
隨堂口試
問下列程式敘述執行後,a,b,c的值各為多少
int a = 1, b = 2, c;
c = a > b ? a++ : b++;
21
邏輯運算子
• 邏輯運算子語法
運算子
意義
語法
&&
且,and
a && b
||
或,or
a || b
!
非,not
! a
• 真值表
變數A
變數B
A&&B
A||B
!A
true
true
true
false
true
false
true
true
false
false
false
false
true
false
false
false
true
false
true
true
22
邏輯運算子
• 運算順序: ! > 關係運算子 > && > ||
• && 和 || 稱為快捷運算子(short circuit)
當a&&b時, 如果知道a為false, 則a&&b一定為false
當a||b時, 如果知道a 為true , 則a||b一定為true, 不用
等b的值
(6<5) && (39>17) && (a==7)
false
不判斷
不判斷
(3<9) || (7<12) || (b<=a)
true
不判斷
不判斷
23
範例3:Ch03_03.java
1.
2.
3.
4.
5.
6.
7.
8.
int a=100, b=100;
boolean c=false, d=false;
System.out.println(6<5 && 39>17 && a==7);
System.out.println(3<9 || 7<12 || b<=a);
c = 3>4 && (d=true);
System.out.println("Try1: c="+c+"\td="+d);
c = 3>2 && (d=true);
System.out.println("Try2: c="+c+"\td="+d);
24
練習5(續)
• 請完成練習5
25
位元運算子
運算子
說明
&
以兩數值逐位元做且(and)運算。
|
以兩數值逐位元做或(or)運算。
~
以一數值逐位元做非(not)運算,也就是取1
補數。
^
以兩數值逐位元做互斥(exclusive or)。兩
位元不一樣時得1,同為0或同為1時得0。
<<
位元左移(left shift)。
>>
位元有號右移(right shift)。
>>>
位元無號右移(unsigned right shift)。
26
位元運算子
• 35變換成二進位為
100011
2
35
17
1
2
35
2
17
1
2
8
1
2
4
0
2
2
0
1
0
27
位元運算子
• &、| 與 ^, 例: 59和38 的位元運算
&
1110112
5910
1001102
3810
1000102
3410
1110112
1110112
| 1001102
^ 1001102
1111112
6310
0111012
2910
28
範例4:位元運算(Ch03_04.java)
//整數型別(int)都可以使用位元運算子
//(byte, char, short)在運算時,會自動轉換為int
1. char a=59;
2. byte b=38;
3. System.out.println( "59 & 38 = " + (a&b) );
4. System.out.println( "59 | 38 = " + (a|b) );
5. System.out.println( "59 ^ 38 = " + (a^b) );
29
位元運算子& | ^
• 利用& 或 | 或 ^ 運算來作位元罩
• 位元罩: 可用來顯示特定的位元
101001 2
& 000100 2
000000 2
100101 2
mask
& 000100 2
mask
000100 2
30
範例5:判斷奇偶數(Ch03_05.java)
//判斷奇數或偶數, 只要檢查最後一碼
1. int i=32, j=17;
2. System.out.println( “i為” + ((i&1)==1 ? “奇
數” : “偶數”) );
3. System.out.println( "j為" + ((j&1)==1 ? "奇數
" : "偶數") );
31
位元運算子~
• 循環性的位元表示法
-2
-3
-1
0
1
2
3
01111111 11111111 11111111 111111112
-2147483646
2147483646
-2147483647
2147483647
-2147483648
10000000 00000000 00000000 000000002
32
範例6:原數加補數(Ch03_07.java)
//經過~運算所得的整數(即1‘s補數)與原整數相
加, 會得到-1
// 主程式部份
1. public static void main(String [] args)
2. {
3.
int i=41;
4.
int j=~i;
5.
System.out.println(i);
6.
printIntBits(i);
7.
System.out.println(j);
8.
printIntBits(j);
9.
System.out.println(i + j);
10. }
33
範例6:Ch03_07.java(續)
//方法printIntBits, 將整數以二進位輸出
1. static void printIntBits(int n)
2. {
3.
int bits = 32;
4.
int m;
5.
for(int i=0; i<bits; i++)
6.
{
7.
m = n >>> (bits-1-i);
8.
System.out.print(m&1);
9.
}
10.
System.out.println("");
11. }
34
範例7:最大整數加1(Ch03_08.java)
//計算一int型別的變數i, 若i為最大int值2147483647
//則i+1會變成負數:-2147483648
1. int i=2147483647;
2. System.out.println(i);
3. printIntBits(i);
4. i+=2;
5. System.out.println(i);
6. printIntBits(i);
7. System.out.println(~i);
8. printIntBits(~i);
35
練習六
利用 | 作為位元罩, 將59轉換為二進位輸出
36
資料型態的轉換
JAVA程式設計入門(I)
型別轉換
• 數值型別的階級
double > float > long > int
• 運算時型別轉換過程
6 + 2.4
6.0 + 2.4
轉換為→
進行加法運算→
6.0 + 2.4
8.4
• 但是byte、short 和 char運算時,全都
轉換為int,所以
short a=1, b=2, c;
c=a+b;
//錯誤!int型別不能指定給short型別
38
型別轉換
• 使用+運算子時,byte和short型別的運
算元會自動轉換成int型別,然而使用++
和+=時,運算元的型別不會轉換
• 變數的常數指定:若常數沒有超出變數可
表現的範圍,則編輯器會將常數轉換成變
數的型別再指定給變數
byte b = 200; //錯誤!found:int
short s = 200; //合法
39
型別轉換
• 運算時的型別自動轉換表
byte short char int long float double
byte
short
char
int
int
int
int
int long float double
int
int
int long float double
int
int long float double
int long float double
long
long float double
float
float double
double
double
40
型別轉換
• 強制型別轉換
– 定型運算子語法:目的型別為Java的
任一基本資型別
(目的型別)運算式
(int)2.75
結果為2
– 由高準確度型別轉換至低準確度型別(型別
降級),其準確度可能會嚴重下降
– 強制型別轉換也可以提高運算結果的
準確度
(float)12/5
或
12/(float)5
41
範例8:Ch03_11.java
1.
2.
3.
4.
5.
6.
7.
int i=8, j=3;
byte a=127, b=1, c;
System.out.println( i/j );
System.out.println( (float)i/j );
System.out.println( i/(float)j );
c=(byte)(a+b);
System.out.println(c);
42
運算子的優先權
單元運算子
算術運算子
位元移動運算子
關係運算子
邏輯運算子
條件運算子
指定運算子
43
運算子的優先權和結合性
優先權等級 運算子
!
1
~
++
-+
說明
結合性
邏輯的「非」
位元的「非」
累加
漸減
負號
正號
由右至左
2
(type)
定型運算子
由右至左
3
*
/
%
乘號
除號
求餘數
由左至右
4
+
-
加號
減號
由左至右
5
<<
>>
>>>
位元左移
位元右移
位元無號右移
由左至右
44
運算子的優先權和結合性
優先權等級
運算子
說明
結合性
6
<
<=
>
>=
是否小於
是否小於等於
是否大於
是否大於等於
由左至右
7
==
!=
是否等於
是否不等於
由左至右
8
&
位元的「且」
由左至右
9
^
位元的「互斥」
由左至右
10
|
位元的「或」
由左至右
11
&&
邏輯的「且」
由左至右
12
||
邏輯的「或」
由左至右
13
?:
條件運算子
由右至左
14
=
+=, -=, *=, /=, %=,
&=, |=, ^=, <<=, >>=,
>>>=
指定運算子
指定類運算子
由右至左
45
練習七
假設您步行的速度為每秒 1 公尺, 而您的朋友
小華步行的速度則為每秒 30 英吋, 如果你們
兩人在距離 200 公尺的操場面對面前進, 請撰
寫程式計算出多久會相遇? (1 英吋等於 2.54
公分)
練習八
假設某個停車場的費率是停車 2 小時以內, 每
半小時 30 元, 超過 2 小時, 但未滿 4 小時的部
分, 每半小時 40 元, 超過 4 小時以上的部分,
每半小時 60 元, 未滿半小時部分不計費。如
果您從早上 10 點 23 分停到下午 3 點 20 分,
請撰寫程式計算共需繳交的停車費。
SCJP 模擬試題(1)
1. Given the following code:
1.
2.
3.
4.
5.
6.
7.
8.
public class Compare {
public static void main(String[] argv) {
String s = "12";
int i = s;
long j = 12;
System.out.println("(i == j) is " + (i == j));
}
}
What is the result?
A. (i == j) is false
B. (i == j) is true
C. Compilation fails at line 4.
D. Compilation fails at line 6.
E. There is a runtime error.
SCJP 模擬試題(2)
2.Given the following code:
1.
2.
3.
4.
5.
6.
public class StrAdd {
public static void main(String[] argv) {
String s = "55" + '5';
System.out.println("Output: " + (s += 3));
}
}
What is the result?
A. Output: 558
B. Output: 5553
C. Compilation fails at line 3
D. Compilation fails at line 4
E. There is a runtime error
SCJP 模擬試題(3)
3. Given the following code:
1.
2.
3.
4.
5.
6.
7.
public class Xvalue {
public static void main(String[] argv) {
String s = "123";
// insert code here
System.out.println("x = " + x);
}
}
Which, inserted at line 4, will compile correctly? (Choose all that apply.)
A. float x = 128.5;
B. double x = s.length();
C. byte x = (byte) 120 + 1;
D. short x = s.length();
E. int x = 255L;
SCJP 模擬試題(4)
4. Given the following code:
1.
2.
3.
4.
5.
6.
7.
8.
9.
public class TestStr {
public static void main(String[] argv) {
String s = "123";
int i = 3, j = 5;
if (i = s.length())
s += (i++) + i;
System.out.println("s = " + s);
}
}
What is the result?
A. s = 1236
B. s = 1237
C. s = 1238
D. Compilation fails.
E. Runtime error.
SCJP 模擬試題(5)
5. Given the following code:
1.
2.
3.
4.
5.
6.
7.
8.
public class Calc {
public static void main(String[] argv) {
int i = 3, j = 2, k = 1;
if ((--i == j) || (i == j++))
k += (i == j? i++ : ++j);
System.out.println("ijk = " + i + j + k);
}
}
What is the result?
A. 245
B. 321
C. 323
D. 333
E. 345
SCJP 模擬試題(6)
6. Given the following code:
1.
public class foo {
2.
public static void main (String[] argv) {
3.
int i = 0xFFFFFFF1;
4.
int j = ~i;
5.
System.out.println(j);
6.
}
7. }
What is the printed value of j?
A. 14
B. -14
C. 15
D. –15
E. An error at line 3 causes compilation fails.
SCJP 模擬試題(7)
Which two of following declarations are illegal?
public class Decli {
public static void main(String[] args) {
int
i = 0xFEDBA987; // S1
char c = 65535;
// S2
char d = -32767;
// S3
short j = -32767;
// S4
long L = 0x123456789; // S5
byte b = (byte)65535; // S6
}
}
A. S1
B. S2
C. S3
D. S4
E. S5
F. S6