運算符
文章目錄
運算符:
1、算術運算符
2、賦值運算符
3、比較運算符(關係運算符)
4、邏輯運算符
5、條件運算符
6、位運算符
表達式:操作數+運算符
1、按照操作數個數的分類:
(1)一元運算符:操作數只有一個
例如:正號(+),負號(-),自增(++),自減(–),邏輯非(!),按位取反(~)
(2)二元運算符:操作數有兩個
例如:加(+),減(-),乘(*),除(/),模(%)
大於(>),小於(<),大於等於(>=),小於等於(<=),等於(==),不等於(!=)
賦值(=,+=,-=,*=,/=,%=,>>=,<<=。。。)
邏輯與(&),邏輯或(|),邏輯異或(^),短路與(&&),短路或(||)
左移(<<),右移(>>),無符號右移(>>>),按位與(&),按位或(|),按位異或(^)
(3)三元運算符:操作數三個
例如: ? :
2、Java基本數據類型的運算符:
(1)算術運算符
(2)賦值運算符
(3)比較運算符
(4)邏輯運算符
(5)條件運算符
(6)位運算符(難)
1、 算術運算符
加法:+
減法:-
乘法:*
除法:/
注意:整數與整數相除,只保留整數部分
取模:% 取餘 被模數%模數
注意:取模結果的正負號只看被模數
特殊:模數的負號被忽略
正號:+
+:作爲單目運算時表示正數 正號:+
與其他基本數據類型計算時當做加法用 a + b
在JAVA中:+ 還表示拼接
只要+兩邊有一個是字符串,那麼就是拼接,結果仍然是字符串
a + “+”:a變量的值 拼接上 “+”符號 ,當與字符串String類型進行運算時表示連接,計算結果是字符串String類型 “菜”+“牛” “菜牛”
負號:-
-
作爲單目運算符時表示負數 -5
與其他基本數據類型計算時當做減法用 a-b
自增:++
自減:–
原則:自增與自減
++/–在前的,就先自增/自減,後取值
++/–在後的,就先取值,後自增/自減
整個表達式的掃描,是從左往右掃描,如果後面的先計算的,那麼前面的就暫時先放到“操作數棧”中
對於自增變量本身來說,++在前或在後都一樣,自增變量都要加1
i++或++i,i就是自增變量對於表達式來說,i++和++i不一樣的,++在前,先自增,再進行其他運算,++在後,先進行其他運算,然後再自增
代碼示例:
int i = 1;
i++;//i=2
int j = 1;
++j;//j=2
int a = 1;
int b = a++;//(1)先取a的值“1”放操作數棧(2)a再自增,a=2(3)再把操作數棧中的"1"賦值給b,b=1
int m = 1;
int n = ++m;//(1)m先自增,m=2(2)再取m的值“2”放操作數棧(3)再把操作數棧中的"2"賦值給n,n=1
int i = 1;
int j = i++ + ++i * i++;
/*
從左往右加載
(1)先算i++
①取i的值“1”放操作數棧
②i再自增 i=2
(2)再算++i
①i先自增 i=3
②再取i的值“3”放操作數棧
(3)再算i++
①取i的值“3”放操作數棧
②i再自增 i=4
(4)先算乘法
用操作數棧中3 * 3 = 9,並把9壓會操作數棧
(5)再算求和
用操作數棧中的 1 + 9 = 10
(6)最後算賦值
j = 10
*/
2、 賦值運算符
基本賦值運算符:=
擴展賦值運算符:+=,-=,*=,/=,%=…
賦值:assign
最基本的賦值運算符:=
Java中賦值,永遠是把等號=右邊的賦值給左邊的變量。
右邊如果是常量值,那麼就把常量的值直接賦值給左邊的變量;
右邊如果是變量,那麼就把變量的值直接賦值給左邊的變量;
右邊如果是表達式,那麼就把表達式的運算結果直接賦值給左邊的變量;
擴展的賦值運算符:
+=,-=,*=,/=,%=
注意:
(1)+=等,中間是不能有空格的,即不能寫成 + =
(2)如果結果的類型與左邊的變量不在一樣時,隱含了強制類型轉換
注意:所有的賦值運算符的=左邊一定是一個變量
擴展賦值運算符=右邊的計算結果的類型如果比左邊的大的話會強制類型轉換,所以結果可能有風險。
擴展賦值運算符的計算:(1)賦值最後算(2)加載數據的順序是把左邊的變量的值先加載,再去與右邊的表達式進行計算
int i = 1;
int j = 5;
j *= i++ + j++;//j = j *(i++ + j++);
/*
(1)先加載j的值“5”
(2)在計算i++
①先加載i的值“1”
②再i自增,i=2
(3)再計算j++
①先加載j的值"5"
②再j自增,j=6
(4)算 加法
i + 5 = 6
(5)算乘法
5 * 6 = 30
(6)賦值
j = 30
*/
3、 比較運算符
關係運算符,比較運算符:運算的結果只有true或false的布爾值
(1)> < >= <= !=
(2)== 判斷是否相等,一定要與=賦值運算符區分開
(3)instanceof,引用數據類型的關係運算符.
大於:>
小於:<
大於等於:>=
小於等於:<=
等於:== 注意區分賦值運算符的=
不等於:!=
注意:比較表達式的運算結果一定只有true/false
比較表達式可以作爲
(1)條件
(2)邏輯運算符的操作數
4、 邏輯運算符
邏輯運算符的操作數必須是布爾值,結果也是布爾值
邏輯與:&
運算規則:只有左右兩邊都爲true,結果才爲true。
例如:true & true 結果爲true
false & true 結果爲false
true & false 結果爲false
false & false 結果爲false
邏輯或:|
運算規則:只要左右兩邊有一個爲true,結果就爲true。
求的就是個性,不同,兩個操作數不同時,結果爲真,如果相同就爲假
例如:true | true 結果爲true
false | true 結果爲true
true | false 結果爲true
false | false 結果爲false
邏輯異或:^
運算規則:只有左右兩邊不同,結果才爲true。
例如:true ^ true 結果爲false
false ^ true 結果爲true
true ^ false 結果爲true
false ^ false 結果爲false
邏輯非:!
運算規則:布爾值取反
例如:!true 爲false
!false 爲true
短路與:&&
運算規則:只有左右兩邊都爲true,結果才爲true。
例如:true & true 結果爲true
true & false 結果爲false
false & ? 結果就爲false
它和邏輯與不同的是當&&左邊爲false時,右邊就不看了。
短路或:||
運算規則:只要左右兩邊有一個爲true,結果就爲true。
例如:true | ? 結果爲treu
false | true 結果爲true
false | false 結果爲false
它和邏輯或不同的是當||左邊爲true時,右邊就不看了。
開發中一般用短路與和短路或比較多
面試題:&& 和 &的區別?
&&當左邊爲false,右邊不計算
&不管左邊是true還是false,右邊都要計算
5、 條件運算符
? :
語法格式:
條件表達式 ? 結果表達式1 : 結果表達式2
注意條件表達式結果必須是布爾類型
運算規則:
整個表達式的結果:當條件表達式爲true時,就取結果表達式1的值,否則就取結果表達式2的值
代碼示例:
(1)boolean類型
boolean marry = true;
System.out.println(marry? "已婚" : "未婚");
(2)求最值
int i = 3;
int j = 5;
int max = i>=j ? i : j;
//當i>=j時,max就賦值爲i的值,否則就賦值爲j的值
(3)求三個數的最大值
//找出三個整數中的最大值
int x = 3;
int y = 2;
int z = 5;
int max = x>=y ? x : y;
//運行到這裏,max中存的是x,y中較大者
max = max >= z ? max : z;
System.out.println("max = " + max);
6、 位運算符
位運算符
效率很高,但是可讀性不好
因爲它是基於二進制補碼直接運算的。
數軸來移動 比較好點來理解 不要這樣理解右移除以2的幾次方左移乘以2的幾次方
用得好很高的效率 但可能很多程序員理解不好的
位運算符:操作數是整數
左移 << :右邊補0
右移 >> :左邊補0或1,原數最高位是1,就補1,原數最高位是0,就補0
無符號右移 >>>:左邊補0
二進制位 變化 移動
/**
* 位運算符 - 移位
* 1、>> 向右移位,使用方法爲 x >> n 表示 x 向右移動 n 位
* 對於正數來說,向右移位時,高位補0,低位被擠掉
* 對於負數來說,向右移位時,高位補1,低位被擠掉
*
* 2、<< 向左移位,使用方法爲 x << n 表示 x 向左移動 n 位
* 不論是正數還是負數,向左移位時,都是擠掉高位,低位補0
*
* 3、>>> 無符號右移
* 不論是正數還是負數,向右移位時,高位一律補0,低位被擠掉
*
* 4、Java 中沒有 <<< 運算符 【劃重點】 有<<就行了
*/
eg:
public class BitOperator1 {
public static void main(String[] args) {
// 被 final 修飾的變量被稱作【最終變量】,它是最終的、不可更改的變量 【不要當做"常量"對待】
final int x = 5 ; // 0b00000000_00000000_00000000_00000101
System.out.println( x );
// 嘗試再次爲 final 修飾的變量賦值
// x = 6 ; // 錯誤: 無法爲最終變量x分配值
// 將 最終變量 x 中存儲的數值向右移動1位後賦值給 y 變量
int y = x >> 1 ; // 0b0_00000000_00000000_00000000_0000010
System.out.println( y );
int z = x << 1 ; // 0b0000000_00000000_00000000_00000101_0
System.out.println( z );
System.out.println( "~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~" );
// -5【原碼】: 1000_0000_0000_0000_0000_0000_0000_0101
// -5【反碼】: 1111_1111_1111_1111_1111_1111_1111_1010
// -5【補碼】: 1111_1111_1111_1111_1111_1111_1111_1011
final int m = -5 ; // 0b1111_1111_1111_1111_1111_1111_1111_1011
System.out.println( m );
int n = m >> 1 ; // // 0b1_1111_1111_1111_1111_1111_1111_1111_101
//【補碼】1_1111_1111_1111_1111_1111_1111_1111_101
//【反碼】1_1111_1111_1111_1111_1111_1111_1111_100
//【原碼】1_0000_0000_0000_0000_0000_0000_0000_011
System.out.println( n );
System.out.println( "~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~" );
int p = m << 1 ; // 0b111_1111_1111_1111_1111_1111_1111_1011_0
//【補碼】111_1111_1111_1111_1111_1111_1111_1011_0
//【反碼】111_1111_1111_1111_1111_1111_1111_1010_1
//【原碼】100_0000_0000_0000_0000_0000_0000_0101_0
System.out.println( p );
System.out.println( "~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~" );
int r = 0x7FFFFFFF ;
System.out.println( r );
int s = r << 1 ;
System.out.println( s );
}
}
public class BitOperator2 {
public static void main(String[] args) {
final int x = 5 ; // 0b00000000_00000000_00000000_00000101
final int y = -5 ; // 0b1111_1111_1111_1111_1111_1111_1111_1011
System.out.println( x >> 1 ); // 0b0_00000000_00000000_00000000_0000010
System.out.println( y >> 1 ); // 0b1_1111_1111_1111_1111_1111_1111_1111_101
System.out.println( "~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~" );
System.out.println( x >>> 1 ); // 0b0_00000000_00000000_00000000_0000010
System.out.println( y >>> 1 ); // 0b0_1111_1111_1111_1111_1111_1111_1111_101
}
}
<<
運算規則:左移幾位感覺就相當於乘以2的幾次方
二進制補碼左移n位,右邊補0
右移:>>
運算規則:右移幾位感覺就相當於除以2的幾次方
無符號右移:>>>
運算規則:往右移動後,左邊空出來的位直接補0,不看符號位
/**
* 位運算符
* 1、| 按位或 ( 逐位或 )
* 2、& 按位與 ( 逐位與 )
* 3、^ 按位異或 (逐位異或 )
* 4、~ 按位取反 (逐位取反) 【注意連符號位也一起取反】
*/
eg:
public class BitOperator4 {
public static void main(String[] args) {
final int x = 5 ; // 0b00000000_00000000_00000000_00000101
final int y = 7 ; // 0b00000000_00000000_00000000_00000111
//【 5 】0b00000000_00000000_00000000_00000101
//【 7 】0b00000000_00000000_00000000_00000111
int a = x | y ; // 按位或: 0b00000000_00000000_00000000_00000111
System.out.println( a );
//【 5 】0b00000000_00000000_00000000_00000101
//【 7 】0b00000000_00000000_00000000_00000111
int b = x & y ; // 按位與: 0b00000000_00000000_00000000_00000101
System.out.println( b );
//【 5 】0b00000000_00000000_00000000_00000101
//【 7 】0b00000000_00000000_00000000_00000111
int c = x ^ y ; // 按位異或: 0b00000000_00000000_00000000_00000010
System.out.println( c );
System.out.println( "~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~" );
int r = 5 ; // 0b00000000_00000000_00000000_00000101
int s = 7 ; // 0b00000000_00000000_00000000_00000111
System.out.println( "r = " + r + " , s = " + s );
// int temp = s ; s = r ; r = temp ;
r = r ^ s ; // 0b00000000_00000000_00000000_00000010
s = r ^ s ; // 0b00000000_00000000_00000000_00000101
r = r ^ s ; // 0b00000000_00000000_00000000_00000111
System.out.println( "r = " + r + " , s = " + s );
System.out.println( "~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~" );
int j = 5 ; // 0b00000000_00000000_00000000_00000101
// 注意使用 ~ 按位取反時,會對整數的符號位也取反
int k = ~j ; //0b11111111_11111111_11111111_11111010
//【補碼】 11111111_11111111_11111111_11111010
//【反碼】 11111111_11111111_11111111_11111001
//【原碼】 10000000_00000000_00000000_00000110
System.out.println( "j = " + j + " , k = " + k );
}
}
按位與:&
運算規則:
1 & 1 結果爲1
1 & 0 結果爲0
0 & 1 結果爲0
0 & 0 結果爲0
按位或:|
運算規則:
1 | 1 結果爲1
1 | 0 結果爲1
0 | 1 結果爲1
0 & 0 結果爲0
按位異或:^
運算規則:
1 ^ 1 結果爲0
1 ^ 0 結果爲1
0 ^ 1 結果爲1
0 ^ 0 結果爲0
按位取反:~
運算規則:~0就是1
~1就是0
如何區分&,|,^是邏輯運算符還是位運算符?
如果操作數是boolean類型,就是邏輯運算符,如果操作數是整數,那麼就位運算符。
總結
位運算符:操作數是整數
左移 << :右邊補0
右移 >> :左邊補0或1,原數最高位是1,就補1,原數最高位是0,就補0
無符號右移 >>>:左邊補0
按位與 & :二進制對應位置取與 ,同時爲1才爲1,否則爲0
按位或 | :二進制對應位置取或 ,有一個爲1就爲1
按位異或運算 ^ :二進制對應位置取異或 ,兩者不同才爲1
按位取反 ~ :二進制對應位置取反 ,原來是1,變爲0,原來是0變爲1
說明:位運算符都是機器數直接運算的
7、 運算符優先級
算符優先級:
(1)賦值類運算符是最低的,即賦值最後算
(2)條件運算符
(3)||-> &&-> |-> ^-> & 短路 邏輯
(4)比較運算符
(5)左移右移的位運算符 << >> >>> 無符號右移:>>>
(6)算術運算符
乘、除、模高於加和減
(7)自增,自減,以及按位取反,非 ! ~
(8).(面向對象用)和()
我們如果要準確的記憶每一種運算符的優先級是困難的。
我們遵循一個原則:
(1)表達式不要寫太複雜,可以分爲多行
(2)如果非要混合運算,那麼先算的用()括起來
關於&,|,^,看左右兩邊的操作數是boolean值,還是整數,來決定是邏輯運算符還是位運算符。
整數是位運算符 ^ 異或 運算符
提示說明:
(1)表達式不要太複雜
(2)先算的使用()
8、 運算符操作數類型說明
1、算術運算符
數字和單個字符可以使用算術運算符。
其中+,當用於字符串時,表示拼接。
2、賦值運算符
右邊的常量值、表達式的值、變量的值的類型必須與左邊的變量一致或兼容(可以實現自動類型轉換)或使用強制類型轉換可以成功。
3、比較運算符
其他的比較運算符都是隻能用於8種基本數據類型。
其中的==和!=可以用於引用數據類型的比較,用於比較對象的地址。(後面講)
int i = 10;
int j = 10;
System.out.println(i==j);//true
char c1 = '帥';
char c2 = '帥';
System.out.println(c1 == c2);//true
4、邏輯運算符
邏輯運算符的操作數必須是boolean值
5、條件運算符
?前面必須是條件,必須是boolean值
結果表達式1和結果表達式2要保持類型一致或兼容
6、位運算符
一般用於整數系列
以上運算符都是針對基本數據類型設計的。
能夠用於引用數據類型只有基本的賦值運算符=,和比較運算符中的==和!=。其他運算符都不能用於引用數據類型。
其中字符串類型還有一個+,表示拼接。
9、code
算術運算符
/*
運算符:
1、算術運算符
加:+
減:-
乘:*
除:/
特殊:整數/整數,結果只保留整數部分
取模(取餘):%
特殊:只看被模數的正負號
被模數%模數
什麼是取模呢 取餘呢
2%3=2
正號:+
負號:-
自增 自己加自己不是的 是自己增加1
自增:++
對於自增變量本身來說,都會+1.
但是++在前還是在後,對於整個表達式的計算來說是不一樣的。
++在前,先自增,然後取自增後變量的值,
++在後,先取變量的值,然後變量自增。
但是不管怎麼樣,自增變量的取值與自增操作一前一後一定是一起完成的。
自減:--
類同自增
*/
class Test05_Arithmetic{
public static void main(String[] args){
int x = 10;
int y = 3;
//System.out.println("x + y = " + x + y);//變爲拼接
System.out.println("x + y = " + (x + y));
System.out.println("x - y = " + (x - y));
System.out.println("x * y = " + (x * y));
System.out.println("x / y = " + (x / y));
System.out.println("x % y = " + (x % y));
System.out.println("----------------------------------");
//特殊:只看被模數的正負號
System.out.println("5%2 = " + 5%2);//1
System.out.println("-5%2 = " + -5%2);//-1
System.out.println("5%-2 = " + 5%-2);//1
System.out.println("-5%-2 = " + -5%-2);//-1
System.out.println("----------------------------------");
int a = -3;
System.out.println(-a);//3
System.out.println("----------------------------------");
int i = 2;
i++;
System.out.println("i = " + i);//3
int j = 2;
++j;
System.out.println("j = " + j);//3
System.out.println("----------------------------------");
int m = 1;
int n = ++m;//m先自增,然後把m的值取出來賦值給n
System.out.println("m = " + m);//2
System.out.println("n = " + n);//2
System.out.println("----------------------------------");
int p = 1;
int q = p++;//(1)先取出p的值"1",先放到一個“操作數棧”,(2)然後p變量完成自增(3)把剛纔放在“操作數棧”中的值賦值給q
System.out.println("p = " + p);//2
System.out.println("q = " + q);//1
System.out.println("q = " + (q = q++));//1
System.out.println("q = " + q);//1
System.out.println("----------------------------------");
int z = 1;
z = z++;//(1)先取出z的值"1",先放到一個“操作數棧”,(2)然後z自增,變爲2(3)把剛纔放在“操作數棧”中的值賦值給z
System.out.println("z = " + z);//1
System.out.println("z = " + z++);//1
System.out.println("z = " + z);//2
System.out.println("z = " + ++z);//3
System.out.println("----------------------------------");
int b = 1;
int c = 2;
/*
第一個:b++
(1)先取b的值“1”,先放到一個“操作數棧”,
(2)緊接着b就自增了,b=2
操作數棧
第二步:++b
(1)先b自增,b=3
(2)緊接着再取b的值“3”,先放到一個“操作數棧”,
第三步:++b
(1)先b自增,b=4
(2)緊接着再取b的值“4”,先放到一個“操作數棧”,
第四步:c++
(1)先取c的值“2”,先放到一個“操作數棧”,
(2)緊接着c自增,c=3
第五步:算乘 ++b和c++的乘法部分
4*2 = 8 然後在壓回“操作數棧”,
第六步:再算 b++ + ++b + 乘的結果
1 + 3 + 8 = 12
*/
int d = b++ + ++b + ++b * c++;
System.out.println("b = " + b);//4
System.out.println("c = " + c);//3
System.out.println("d = " + d);//12
}
}
練習
class Test06_Exer3{
public static void main(String[] args){
int i = 1;
int j = 2;
/*
第一步:++i
(1)先自增,i=2
(2)在取i的值“2”,放起來
第二步:j
(1)取j的值“2”,放起來
第三步:++i
(1)先自增,i=3
(2)在取i的值"3",放起來
第四步:求乘積
2 * 3 = 6,結果放起來
第五步:求和
2 + 6 = 8
*/
System.out.println(++i + j * ++i);
}
}
/*
已知一個三位數,例如:483,如何用代碼求出它的百位、十位、個位數
*/
class Test07_Exer4{
public static void main(String[] args){
int num = 483;
int bai = num / 100;// 483/100 4
//int shi = num/10%10;// 483/10 48 48%10 8
int shi = num%100/10;// 483%100 83 83/10 8
int ge = num % 10;// 483%10 3
System.out.println(num + "的百位:" + bai + ",十位:" + shi +",個位:" + ge);
//483的百位:4,十位:8,個位:3
}
}
//字符串拼接
class Test08_Exer6{
public static void main(String[] args){
int no = 10;
String str = "abcdef";
String str1 = str + "xyz" + no;//abcdefxyz10
str1 = str1 + "123";//abcdefxyz10123
char c = '國';
double pi = 3.1416;
str1 = str1 + pi;//abcdefxyz101233.1416
boolean b = false;
boolean t = true;
System.out.println("" + b + t);//falsetrue
System.out.println(b + "" + t);//falsetrue
/*
System.out.println(b + t + "");
Error:(22, 30) java: 二元運算符 '+' 的操作數類型錯誤
第一個類型: boolean
第二個類型: boolean
* */
str1 = str1 + b;//abcdefxyz101233.1416false
str1 = str1 + c;//abcdefxyz101233.1416false國
String f = "false";
System.out.println(b + f);//falsefalse
System.out.println(f + b);//falsefalse
System.out.println("str1 = " + str1);
}
}
//什麼是求和 什麼是拼接
class Test08_Exer7{
public static void main(String[] args){
/*
String str1 = 4;
左邊是String字符串類型,右邊是4int類型,它們之間無法自動類型轉換
*/
//String str1 = 4;
String str2 = 3.5f + "";
System.out.println(str2); //3.5
System.out .println(3+4+"Hello!"); //7Hello!
System.out.println("Hello!"+3+4); // Hello!34
System.out.println('a'+1+"Hello!"); // 98Hello!
System.out.println("Hello"+'a'+1); //Helloa1
}
}
class Test08_Exer8{
public static void main(String[] args){
short s = 5;
// s = s-2; //short - int,結果是int
// int賦值給short Error:(8, 14) java: 不兼容的類型: 從int轉換到short可能會有損失
byte b = 3;
// b = b + 4; //byte + int,結果是int
//Error:(12, 17) java: 不兼容的類型: 從int轉換到byte可能會有損失
b = (byte)(b+4); //可以
System.out.println(b);// 3+4 7
char c = 'a';
int i = 5;
float d = .314F;//非標準寫法,如果整數部分是0,可以省略0,但不能省略小數點
double result = c+i+d; //char + int + float,結果是float,然後自動升級爲double
byte byte1 = 5;
short short1 = 3;
// short t = short1 + byte1; //short + byte,結果是int
//Error:(24, 26) java: 不兼容的類型: 從int轉換到short可能會有損失
int t = short1 + byte1; //short + byte,結果是int
System.out.println(t);//8
}
}
賦值運算符
/*
運算符:
2、賦值運算符
(1)基本的賦值運算符:=
賦值操作:永遠是把=右邊的常量值、變量中值、表達式計算的值賦值給=左邊的變量,
即=左邊只能是一個變量。
運算的順序:把右邊的整個表達式先算完,纔會做最後的賦值操作。
(2)擴展的賦值運算符
例如:
+=
-=
*=
/=
%=
...
*/
class Test09_Assign{
public static void main(String[] args){
int x = 1;
int y = 2 ;
int z = 3;
// x + y = z;//=左邊只能是一個變量
//Error:(31, 11) java: 意外的類型
// 需要: 變量
// 找到: 值
byte b1 = 1;
byte b2 = 2;
//b2 = b1 + b2;//右邊byte + byte結果是int
b2 += b1;//等價於 b2 = (byte)(b2 + b1);
System.out.println("b1 = " + b1);//1
System.out.println("b2 = " + b2);//3
System.out.println("---------------------------");
//運算的順序:把右邊的整個表達式先算完,纔會做最後的賦值操作。
int i = 1;
int j = 5;
/*
第一步 i++
(1)先取i的值 放起來
(2)i自增,i=2
第二步 求和
1 + 5 = 6
第三步 乘
j * (和) = 5 * 6 = 30
第四步 賦值 把乘積賦值給j
*/
j *= i++ + j;
System.out.println("i = " + i);//2
System.out.println("j = " + j);//30
}
}
比較運算符
*
運算符:
3、比較運算符
大於:>
小於:<
大於等於:>=
小於等於:<=
等於:==
注意,謹防與賦值的=混淆
不等於:!=
比較運算符,計算完後的結果只有兩個:true,false
說明比較運算符的表達式,可以作爲(1)判斷的條件(2)邏輯運算符的操作數
比較運算符能夠用於基本數據類型,不能用於引用數據類型。
除了==和!=,關於引用數據類型時它倆的意義後面再講。
操作數幾元
一元運算符:操作數只有一個
例如:a++ 其中a就是操作數
-a 其中a就是操作
二元運算符:需要兩個操作數
例如:求和 a+b 其中a和b就是操作
比較大小 age>=18 其中的age和18都是操作數
三元運算符:需要三個操作數
...
*/
class Test10_Compare{
public static void main(String[] args){
/*
有一個變量age,表示年齡,判斷是否成年(滿足18歲)
*/
int age = 26;
System.out.println("是否成年:" + (age>=18));//是否成年:true
// System.out.println("是否成年:" + age>=18);//這是先字符串拼接的
/*
比較運算符作爲條件
*/
if(age >= 18){
System.out.println("祝你玩得愉快!");
}else{
System.out.println("未成年不得進入!");
}
/*
有一個變量,存儲的是boolean類型的值
*/
boolean flag = false;
if(flag == true){//不會修改flag裏面的值
System.out.println("條件成立1");
}
//與上面的語句是等價的
if(flag){
System.out.println("條件成立2");
}
if(flag = true){//不是比較,而是賦值,結果仍然是布爾值,只要是布爾值就可以作爲條件
System.out.println("條件成立3");
}
System.out.println("flag = " + flag);
/*
有一個變量,存儲的是其他類型的值
*/
int num = 1;
if(num == 1){
System.out.println("num=1");
}
//true false 纔是 最終的情況
//if(num = 1){//錯誤的,因爲num=1是賦值表達式,結果還是int,int值是不能作爲條件的
// System.out.println("num=1");
//}
}
}
邏輯運算符
/*
運算符:
4、邏輯運算符
邏輯與:&
類似於:且
true & true 結果爲true
true & false 結果爲false
false & true 結果爲false
false & false 結果爲false
多個條件是否兩個都成立 兩個都滿足的
邏輯或:|
類似於:或
true | true 結果爲true
true | false 結果爲true
false | true 結果爲true
false | false 結果爲false
滿足一個 爲true
邏輯非:!
類似於:取反
!true 結果爲false
!false 結果爲true
邏輯異或:^
類似於:求不同
true ^ true 結果爲false
true ^ false 結果爲true
false ^ true 結果爲true
false ^ false 結果爲false
求不同 不同的爲true 一樣的爲false
短路與:&&
結果:和&是一樣的
運算規則:如果&&的左邊已經是false,右邊就不看了
true & true 結果爲true
true & false 結果爲false
false & ? 結果爲false
false & ? 結果爲false
段路運算
短路或:||
結果:和|是一樣的
運算規則:如果||左邊已經是true,右邊就不看了
true | ? 結果爲true
true | ? 結果爲true
false | true 結果爲true
false | false 結果爲false
*/
class Test11_Logic{
public static void main(String[] args){
/*
判斷成績是否在70和80之間
數學:70<=score<=80
Java中:
*/
int score = -78;
/*
Test11_Logic.java:14: 錯誤: 二元運算符 '<=' 的操作數類型錯誤
if( 70<=score<=80){
^
第一個類型: boolean 70<=score的運算結果是true或false
第二個類型: int
1 個錯誤
false<=80 int
*/
//if( 70<=score<=80){
// System.out.println("良好");
//}
if(70<=score & score<=80){
System.out.println("良好");
}
/*
假設成績合理範圍[0,100]
判斷成績是否小於0 或 大於100,輸出成績有誤
*/
if(score<0 | score>100){
System.out.println("成績有誤");
}
/*
假設成績合理範圍[0,100]
判斷成績是否在合理範圍內
*/
if(score>=0 & score<=100){
}
//或下面這麼寫
if(!(score<0 | score>100)){
}
System.out.println(true ^ true);
System.out.println(true ^ false);
System.out.println(false ^ true);
System.out.println(false ^ false);
/*
短路與:&&
短路或:||
*/
int i = 1;
int j;
/*
第一步:i++
(1)先取i的值“1”,放起來
(2)在i自增,i=2
第二步:算比較
放起來的“1” == 1比較,成立
&&左邊是true,不會短路
第三步:++i
(1)先自增i=3
(2)再取i的值“3”,放起來
第四步:比較
放起來的“3” == 2比較,結果是false,不成立
第五步:
左邊的true && 右邊的false運算,結果爲false,總的if不成立,走else
*/
//if(i++ == 1 && ++i == 2){
// j = 1;
//}else{
// j = 2;
//}
/*
第一步:i++
(1)先取i的值“1”,放起來
(2)在i自增,i=2
第二步:算比較
放起來的“1” == 1比較,成立
||左邊是true,會發生短路,右邊不看了(++i == 2)沒運算
第三步:
true || ?,結果爲true,總的if成立
*/
if(i++ == 1 || ++i == 2){
j = 1;
}else{
j = 2;
}
System.out.println("i = " + i);
System.out.println("j = " + j);
}
}
練習
class Test12_Exer1{
public static void main(String[] args){
int x = 1;
int y = 1;
/*
第一步:x++
(1)先取x的值“1”
(2)再x自增x = 2
第二步:比較
用“1”與2比較, 1==2,不成立,false
因爲&不是短路與,不管左邊是怎麼樣,右邊繼續
第三步:++y
(1)自增 y = 2
(2)取y的值“2”
第四步:比較
用“2”與2比較 2 == 2,成立,true
第五步:邏輯
false & true,結果爲false,總的if不成立
*/
if(x++ == 2 & ++y==2){
x = 7;
}
//& 兩個都要處理的
System.out.println("x = " + x + ",y = " + y);//x = 2,y = 2
}
}
class Test12_Exer2{
public static void main(String[] args){
int x = 1;
int y = 1;
/*
第一步:x++
(1)先取x的值“1”
(2)再x自增x = 2
第二步:比較
用“1”與2比較, 1==2,不成立,false
因爲&&是短路與,左邊爲false,右邊就不看了
第三步:邏輯
false & ?,結果爲false,總的if不成立
*/
//x=1 y=1
if(x++ == 2 && ++y==2){
x = 7;
}
System.out.println("x = " + x + ",y = " + y);//x = 2,y = 1
}
}
class Test12_Exer3{
public static void main(String[] args){
int x = 1;
int y = 1;
/*
第一步:x++
(1)先取x的值“1”
(2)再x自增x = 2
第二步:比較
用“1”與1比較, 1==1,成立,true
中間是|,不是短路或,右邊要繼續
第三步:++y
(1)y先自增,y=2
(2)再去y的值“2”
第四步:比較
用“2”與1比較 2==1,不成立,結果爲false
第五步:邏輯
true & false,結果爲true,總的if成立,要執行x = 7
*/
//
if(x++ == 1 | ++y==1){
x = 7;
}
System.out.println("x = " + x + ",y = " + y);//x = 7,y = 2
}
}
class Test12_Exer4{
public static void main(String[] args){
int x = 1;
int y = 1;
/*
第一步:x++
(1)先取x的值“1”
(2)再x自增x = 2
第二步:比較
用“1”與1比較, 1==1,成立,true
中間是||,是短路或,左邊已經爲true,會發生短路現象,右邊不看了
第五步:邏輯
true & ?,結果爲true,總的if成立,要執行x = 7
*/
// x = 1 ; y =1
if(x++ == 1 || ++y==1){
x = 7;
}
System.out.println("x = " + x + ",y = " + y);//x = 7,y = 1
}
class Test13_Exer{
public static void main(String[] args){
boolean x = true;
boolean y = false;
short z = 42;
/*
第一步:z++
(1)先取z的值“42”
(2)z自增 z=43
第二步:比較
用“42”與42比較,條件成立,true
中間是&&,短路與,但是沒有滿足短路現象。右邊繼續
第三步:
取y的值false
第四步:
比較,用"false"與true比較,條件不成立,false
第五步:
true && false,結果爲false,if條件不成立,z++不執行
*/
if((z++==42) && (y==true))
z++;
/*
||左邊:x=false,這是賦值運算,結果仍然是false
中間||,是短路或,但是沒有滿足短路現象,右邊繼續
右邊:
++z:先自增z=44,然後取z的值“44”,然後與45進行比較,結果爲false
左邊的false || 右邊的false,結果還是false,if不成立,z++不執行
*/
if((x=false) || (++z==45))
z++;
System.out.println("z = " + z);//44
}
}
class Test13_Exer2{
public static void main(String[] args){
boolean x = true;
boolean y = false;
short z = 42;
/*
這裏y=true是賦值,結果還是true,表示條件成立,並且y的值已經變爲true
*/
if(y=true)
/*
第一步:z++
(1)先取z的值“42”
(2)z自增 z=43
第二步:比較
用“42”與42比較,條件成立,true
中間是&&,短路與,但是沒有滿足短路現象。右邊繼續
第三步:
取y的值true
第四步:
比較,用"true"與true比較,條件成立,true
第五步:
true && true,結果爲true,if條件成立,z++執行
z = 44
*/
if((z++==42) && (y==true))
z++;
/*
||左邊:x=false,這是賦值運算,結果仍然是false
中間||,是短路或,但是沒有滿足短路現象,右邊繼續
右邊:
++z:先自增z=45,然後取z的值“45”,然後與45進行比較,結果爲true
左邊的false || 右邊的true,結果還是true,if成立,z++執行,z=46
*/
if((x=false) || (++z==45))
z++;
System.out.println("z = " + z);//46
}
}
條件運算符
/*
運算符:
5、條件運算符,
因爲它是唯一的三元運算符,所以也稱爲三元運算符
條件表達式 ? 結果表達式1 : 結果表達式2
整個表達式包含三個部分。
運算規則:如果條件表達式成立,就取結果表達式1的值,否則就取結果表達式2的值
*/
class Test14_Condition{
public static void main(String[] args){
boolean marry = false;
System.out.println(marry ? "已婚" : "未婚");
//找出x和y中的最大值
int x = 4;
int y = 4;
int max = x>=y ? x : y;
/*
等價於
if(x>=y){
max = x;
}else{
max = y;
}
*/
System.out.println(x + "," + y + "中的最大值是:" + max);
int a = 4;
int b = 5;
int m;
if (a >= b){
m = a;
}else{
m = b;
}
System.out.println(a + ","+ + b + ","+"m:" + m);
int temp = a;
a = b;
b = temp;
m = a>=b ? a : b;
System.out.println();
System.out.println(a + ","+ + b + ","+"m:" + m);
}
}
位運算符
/*
運算符:(瞭解)
6、位運算符
效率很高,但是可讀性不好
因爲它是基於二進制補碼直接運算的。
數軸來移動 比較好點來理解 不要這樣理解右移除以2的幾次方
用得好很高的效率 但可能很多程序員理解不好的
左移:<<
運算規則:<<幾位,就乘以2的幾次方
二進制補碼左移n位,右邊補0
右移:>>
運算規則:>>幾位,就除以2的幾次方
二進制補碼右移n位,左邊補0還是1,看最高位
無符號右移:>>>
運算規則:二進制補碼右移n位,左邊補0,對於負數來說,移完後,變爲正數
沒有 <<< 因爲就是<< 嗯嗯
按位與:&
1 & 1 結果1
1 & 0 結果0
0 & 1 結果0
0 & 0 結果0
按位或:|
1 | 1 結果1
1 | 0 結果1
0 | 1 結果1
0 | 0 結果0
按位異或:^
1 ^ 1 結果0
1 ^ 0 結果1
0 ^ 1 結果1
0 ^ 0 結果0
按位取反:~(一元運算符)
~1爲0
~0爲1
*/
class Test15_Bit{
public static void main(String[] args){
/*
4的二進制:0000 0100
4<<3:0 0100000
*/
System.out.println(4 << -3);//-2147483648 ???
System.out.println(4 << -32);//4
System.out.println(4 << 32);//4
System.out.println(4 << 35);//32
System.out.println(4 << 3);//等價於4乘以2的3次方,4*8=32
/*
32的二進制:0010 0000
32>>4:0000 0010
*/
System.out.println(32 >>4);//等價於32除以2的4次方,32/16 =2
/*
-32的二進制:
原碼:1010 0000
反碼:1101 1111
補碼:1110 0000
-32>>4:1111 1110
補碼:1111 1110
反碼:1111 1101
原碼:1000 0010
負的 右移 補1 少多少補多少
*/
System.out.println(-32 >>4);// -2
System.out.println(32 >>> 4);//和>>一樣,左邊補0 2
/*
-32的二進制:
原碼:1000 0000 0000 0000 0000 0000 0010 0000
反碼:1111 1111 1111 1111 1111 1111 1101 1111
補碼:1111 1111 1111 1111 1111 1111 1110 0000
-32>>>4:0000 1111 1111 1111 1111 1111 1111 1110
最高位是0,是正數
*/
System.out.println(-32 >>> 4);//268435454
/*
32:0000 0000 0000 0000 0000 0000 0010 0000
25:0000 0000 0000 0000 0000 0000 0001 1001
32 & 25:0000 0000 0000 0000 0000 0000 0000 0000
*/
System.out.println(32 & 25);//0
/*
32:0000 0000 0000 0000 0000 0000 0010 0000
25:0000 0000 0000 0000 0000 0000 0001 1001
32 | 25:0000 0000 0000 0000 0000 0000 0011 1001
*/
System.out.println(32 | 25);//57
/*
32:0000 0000 0000 0000 0000 0000 0010 0000
25:0000 0000 0000 0000 0000 0000 0001 1001
32 | 25:0000 0000 0000 0000 0000 0000 0011 1001
*/
System.out.println(32 ^ 25);//57
/*
3:0000 0000 0000 0000 0000 0000 0000 0011
~3:1111 1111 1111 1111 1111 1111 1111 1100
補碼:1111 1111 1111 1111 1111 1111 1111 1100
反碼:1111 1111 1111 1111 1111 1111 1111 1011
原碼:1000 0000 0000 0000 0000 0000 0000 0100 -4
*/
System.out.println(~3);//-4
}
}
運算符優先級
/*
運算符優先級:
(1)賦值類運算符是最低的,即賦值最後算
(2)條件運算符
(3)||-> &&-> |-> ^-> & 短路 邏輯
(4)比較運算符
(5)左移右移的位運算符 << >> >>> 無符號右移:>>>
(6)算術運算符
乘、除、模高於加和減
(7)自增,自減,以及按位取反,非 ! ~
(8).(面向對象用)和()
我們如果要準確的記憶每一種運算符的優先級是困難的。
我們遵循一個原則:
(1)表達式不要寫太複雜,可以分爲多行
(2)如果非要混合運算,那麼先算的用()括起來
關於&,|,^,看左右兩邊的操作數是boolean值,還是整數,來決定是邏輯運算符還是位運算符。
整數是位運算符 ^ 異或 運算符
*/
class Test16_Priority{
}
練習交換兩個變量的值、判斷是否閏年、求最大值
交換兩個變量的值
/*
交換兩個變量的值
藉助於第三個同樣類型的變量
a b c
c = a;
a = b;
b = a;
*/
class Test17_Swap{
public static void main(String[] args){
int x = 1;
int y = 2;
/*
通用的方案:適用於任意的數據類型
藉助於第三個通樣類型的臨時變量
*/
int temp = x;//x變量中值就賦值給了temp temp = 1
x = y;//再把y中的值放到x中,x = 2
y = temp;//再把temp中的值賦值給y y=1
System.out.println("x = " + x);
System.out.println("y = " + y);
temp = x;
x = y;
y = temp;
// x = 1;
// y = 2;
/*
方案二:只適用於int等整數類型 byte short int long
*/
x = x ^ y;
y = x ^ y;//(新的x) ^ 原來的y = (原來的x ^ 原來的y) ^ 原來的y = 原來的x (求不同)
x = x ^ y;//(新的x) ^ 新的y = (原來的x ^ 原來的y) ^ 原來的x = 原來的y
System.out.println("x = " + x);
System.out.println("y = " + y);
// y = x ^ y ^ y; y = x; x = x ^ y ^ x;
x = 1;
y = 2;
/*
方案三:只適用於int等整數類型
有風險,可能會溢出
*/
x = x + y;//有風險,可能會溢出 大了 超了
y = x - y;//(新的x) - 原來的y = (原來的x + 原來的y)- 原來的y = 原來的x
x = x - y;//(新的x) - 新的y = (原來的x + 原來的y) - 原來的x = 原來的y
System.out.println("x = " + x);
System.out.println("y = " + y);
/*
以下不推薦
*/
x = 1;
y = 2;
x = x * y;//風險更大
y = x / y;
x = x / y;
}
}
判斷是否閏年
/*
1、定義一個int類型變量,保存年份,判斷這個年份是否是閏年
注:判斷一年是否是閏年的標準:
1)可以被4整除,但不可被100整除
2)可以被400整除
*/
class Test18_Exer{
public static void main(String[] args){
int year = 2000;
boolean result = year%4==0 && year%100!=0 || year%400==0;
System.out.println(year + (result?"是閏年":"不是閏年"));
if ( year%4==0 && year%100!=0 || year%400==0){
System.out.println(year + "是閏年");
}
}
}
求最大值
//2、定義三個int類型的變量,x,y,z,隨意賦值整數值,求最大值
class Test19_Exer{
public static void main(String[] args){
int x = 23;
int y = 34;
int z = 49;
//int max = x>=y ? x : y;//運行完這句max中存的是x與y中的最大值
//max = max >=z ? max : z;//用新的max與z比較
int max = (x>=y ? x : y) >= z ? (x>=y ? x : y) : z;
System.out.println("max = " + max);
//還不如兩行的
// int min = (x<=y ? x:y) <= z ? (x<=y ? x:y) : z;
// System.out.println("min:" + min);
int min = x<=y ? x:y;//行完這句min中存的是x與y中的最小值
min = min<=z ? min :z;////用新的min與z比較
System.out.println("min:" + min);
}
}