java中的幂运算符号_JavaSE【运算符篇】
1.定义
运算符是⽤来指明对于操作数(运算符左右两侧的数或者变量)的运算⽅式。
2.分类⽅式i.按照操作数数⽬分类。
ii.按照功能分类。
按照运算符操作数的数⽬来进⾏分类可以分为:单⽬、双⽬、三⽬运算符。如:[1]a++,++是单⽬运算符,a是操作数。
[2]a+b,+是双⽬运算符,a和b是操作数。
[3](a>b)?a:b,?:是三⽬运算符,a和b是操作数。
按照运算符的功能来进⾏分类可以分为:赋值、算术、关系、逻辑、条件、位运算符。
根据操作数来分类不便于记忆,因此我们⼀般按照运算符的功能来进⾏分类。
3.赋值运算符
=、+=(递增)、-=(递减)、*=(倍增)、/=、%=
赋值运算符将=号右边的内值存⼊到=号左边的变量空间中去。除了赋值符号=外的都是复合型赋值符号。如:[1]var=value;意思就是把
value的值赋值给var变量。
[2]x+=10;相当于x=x+10;
以下代码会输出什么?
publicstaticvoidmain(String[]args){
bytex=1;
x=x+2;
n(x);
}
编译不通过!这⾥⾸先在变量空间x中取出其内容,然后从常量区复制⼀份2,执⾏加法运算,最后将结果重新存储到变量空间x内。注意,
这⾥的变量空间x是⼀个byte类型的数据1,即只有8个bit位,⽽常量区中的整型常量默认是int类型,这⾥是int类型的常量2,即有32bit
位,然后通过算术运算符+时会⾃动将8bit位的数据1提升为32bit位的数据1,然后再进⾏+运算,最后再将32bit位的结果,即int类型的数
据3赋值给变量空间x,因为变量空间x存储的内容是byte类型,所以会报损失的错误。因此只需将最后的运算结果通过强制类型转换即可解
决这个问题。
publicstaticvoidmain(String[]args){
bytex=1;
x=(byte)(x+2);
n(x);
}
那么为什么bytex=1;能⾃动将int类型的1转化为byte类型的1,⽽x=x+2;不能将int类型的3转化为byte类型的3呢?
因为bytex=1;的1是⼀个常量值,JVM虚拟机编译的时候认识这是⼀个int类型的1,所以能进⾏⾃动类型转换,⽽x=x+2;,JVM虚拟
机编译的时候不认识x+2是什么,只知道是⼀个表达式,所以没有进⾏⾃动类型转换,即表达式x+2的值是多少就直接赋值到=号的左
边,所以会报损失错误。剩下的赋值运算符类似。
⽽+=是⼀个整体,所以可以进⾏⾃动类型转换。
publicstaticvoidmain(String[]args){
bytex=1;
x+=2;
n(x);
}
总结:在进⾏运算符操作时,⾃动类型转化的前提是⼀个已经确定数据类型的变量,才能进⾏⾃动类型转换。
4.算术运算符
+、-、*、/、%(取余)、++(⾃增)、--(⾃减)
注意事项:[1]/在java中表⽰整除,整数和整数运算得到的⼀定是整数;只要有⼩数参与整除/得到的⼀定是⼩数。
[2]/中被除数不能为0。
[3]%取余(求模),模谁就不会超过谁!e.g:5%2结果是1
[4]++/--在前,先+1/-1,后运算。
[5]++/--在后,先运算,后+1/-1。
--需求:给变量x加1有多少种⽅式?[1]X=x+1;
[2]x++;
[3]++x;
这三种⽅式在内存中的执⾏过程是⼀样,⽽++表现形式更加的简洁
--需求:把12345s转化成_时_分_秒
publicstaticvoidmain(String[]args){
intval=12345;
inth=val/3600;
intm=val%3600/60;
ints=val%60;
n(h+":"+m+":"+s);
}
i++/i--
i先参与运算,运算完成i⾃加/⾃减1。
publicstaticvoidmain(String[]args){
//[1]inta=10;
intb=a++;
n("a="+a);//n("b="+b);//10
//[2]intc=10;
c++;
n("c="+c);//11
//[3]intd=10;
inte=d+++d++;
n("d="+d);//n("e="+e);//21}
++i/--i
i在参与运算前就⾃加/⾃减1。
publicstaticvoidmain(String[]args){
//[1]inta=10;
intb=++a;
n("a="+a);//n("b="+b);//11
//[2]intc=10;
++c;
n("c="+c);//11
//[3]intd=10;
inte=++d+++d;
n("d="+d);//n("e="+e);//23}
如果是按照++在操作数前,先执⾏++,++在操作数后,后执⾏++,这种思维那么下⾯的代码会输出什么?
publicstaticvoidmain(String[]args){
inta=1;
a=a++;
n("a="+a);
}
会输出1,在计算机底层中,算术运算的优先级是⾼于赋值运算的,先计算,后赋值。所以,变量想要做值交换(值计算)的时候,会产⽣⼀
个临时的副本空间(备份),如果++在变量的前⾯,先⾃增后备份,如果++在变量的后⾯,先备份后⾃增,最后才会将副本空间中内的值赋
值另⼀个变量。通过这种理解,可以很好的对上⾯的代码进⾏⼀个理解。(任何赋值情况都会开辟⼀个临时的副本空间,如果++在前那么就
先⾃增在开辟,如果++在后那么先开辟再⾃增,最后再将开辟的副本空间中的值赋值赋值运算符左侧的变量空间)。
内存图:
如果理解算术和赋值运算的关系,那么下⾯的笔试题就⾮常好理解了。
publicstaticvoidmain(String[]args){
inta=1;
for(inti=1;i<=100;i++){
a=a++;
}
n("a="+a);
}
注意,在java中不允许定义相同的变量空间,因为变量空间是存储在栈内存中的,⽽且有且只有⼀份,因此不能定义数据类型和变量空间名
相同的变量。
5.关系运算符
>、>=、
其中instanceof⽤于判断⼀个对象对应的类是否能顺着继承链往上找到这个类,返回值为boolean,即true/fal,⽤法:对象
instanceof类。
publicstaticvoidmain(String[]args){
Personperson=newPerson();
Studentstudent=newStudent();
n(personinstanceofPerson);
n(personinstanceofStudent);
}
这⾥Student继承Person类。
⼩数不能⽤于关系运算符的⽐较,因为⼩数的精确程度不准确,如0.1不等于1.0/10;
publicstaticvoidmain(String[]args){
n(0.1==(1/10));
}
=和==的区别?
=赋值符号,将=右侧的结果(原始值/引⽤值)存⼊=左侧的变量空间内。
==⽐较符号,⽐较==左侧和==右侧结果(原始值/引⽤值)是否⼀致。
⽐较运算符的最终结果是什么?
因为⽐较只有两种情况,即true或者fal,所以使⽤布尔型boolean来表⽰。因为布尔类型不能和其他基本数据类型进⾏转换,因此只有
true和fal⽽没有0和1。
6.逻辑运算符
&逻辑与、|逻辑或、^逻辑异或、!逻辑⾮、&&短路与、||短路或
逻辑运算符⽤于罗列⼀堆条件的满⾜情况,是满⾜所有还是满⾜其中⼀个还是⼀个都不满⾜等等之类的问题,逻辑运算符前后连接的是两个
boolean值。其中只有逻辑⾮是⼀个单⽬运算符,逻辑⾮只能在后⾯接⼀个判定表达式。
关系和逻辑运算符的区别?关系运算符只能⽤于⼀个条件的判定。
⽽逻辑运算符既能⽤于⼀个条件也能⽤于多个条件的判定。
逻辑与&,可以理解为中⽂的和或者并且的意思,只有逻辑与&前后两个条件必须同时满⾜,即boolean值都是true,最终才为true。理解
为:⽼师需要张三和李四来⼀趟。
publicstaticvoidmain(String[]args){
booleanb1=(3>2)&(3>4);
n(b1);
booleanb2=(3>2)&(3>1);
n(b2);
}
逻辑或|,可以理解为中⽂或者的意思,逻辑或|前后的两个条件只要有⼀个满⾜,最终就为true。理解为:⽼师让张三或者李四来⼀趟。
publicstaticvoidmain(String[]args){
booleanb1=(3>2)|(3>4);
n(b1);
booleanb2=(3>5)|(3>4);
n(b2);
}
逻辑异或^,异就是不同的意思,所以如果前后两个表达式的结果不⼀致,就为true,即⼀侧为true,⼀侧为fal时逻辑异或^的结果才为
true,否则就为fal,即两侧都是true或者两侧都是fal时逻辑异或^的结果为fal。
publicstaticvoidmain(String[]args){
booleanb1=(3>2)^(3>4);
n(b1);
booleanb2=(3>5)^(3>4);
n(b2);
booleanb3=(3>1)^(3>2);
n(b3);
}
逻辑⾮!,是⼀个单⽬运算符,⾮!是取反的意思,可以理解为中⽂的不,会将后⾯的表达式的boolean的值取反,即true取反为fal,fal
取反为true。
publicstaticvoidmain(String[]args){
booleanb1=!(3>2);
n(b1);
booleanb2=!(3>4);
n(b2);
}
短路与&&,与是两个条件同时满⾜,如果当第⼀个条件已经为fal,最终肯定是fal。i.什么情况下发挥发⽣短路?当前⾯的boolean值
结果为fal的时候会发⽣短路。
ii.到底短路的是什么?短路的是短路与&&之后所有计算的过程。
iii.如果发⽣了短路情况,性能会⽐&稍微好⼀点,因为少判断⼀些表达式的boolean值。
iv.逻辑与&和短路与&&从执⾏的最终结果来看没有任何区别。
v.短路与&&不⼀定提⾼了性能,只有当第⼀个表⽰的boolean值为fal的时候才会发⽣短路,即才会提⾼性能。
publicstaticvoidmain(String[]args){
inta=10;
intb=20;
intc=30;
booleanr2=(a>b)&&(++c>b);
n("r2="+r2);
n("c="+c);
}
短路或||,当第⼀个表达式的boolean值为true时,就终⽌判断了,直接返回true,当第⼀个表达式的boolean值为fal时,就直接返回第
⼆个表达式的boolean值。短路或相对逻辑或在在效率上会有⼀点优势,但不是绝对的,前提条件是第⼀个表达式的boolean值为true。
publicstaticvoidmain(String[]args){
inta=10;
intb=20;
intc=30;
booleanr2=(ab);
n("r2="+r2);
n("c="+c);
}
7.条件运算符
语法:(条件表达式)?(表达式1):(表达式2)
如果条件表达式的值为true,整个表达式的结果取表达式1的结果,否则取表达式2的结果。
publicstaticvoidmain(String[]args){
inta=10;
intb=20;
intc=(a>b)?a:b;
n("c="+c);
}
8.位运算符
按位与&、按位或|、按位异或^、按位取反~、按位左位移<>、⽆符号按位右位移>>>
位运算符主要对⼆进制位进⾏运算。
按位与(&)
publicstaticvoidmain(String[]args){
n(1&2);
}
运算过程:⾸先将1和2转换为⼆进制表⽰,随后,⽐较相同位置上的bit,如果同1才1,否则为0,最后将得到的⼆进制再转换为⼗进制输
出。0001
&0010
-----------------
0000=>0
按位或(|)
publicstaticvoidmain(String[]args){
n(1|2);
}
运算过程:⾸先将1和2转换为⼆进制表⽰,随后,⽐较相同位置上的bit,如果有1就为1,全0才为0,最后将得到的⼆进制再转换为⼗进
制输出。0001
|0010
-----------
0011=>3
按位异或(^)
publicstaticvoidmain(String[]args){
n(1^2);
}
运算过程:⾸先将1和2转换为⼆进制表⽰,随后,⽐较相同位置上的bit,如果相同就为0,不同才为1,最后将得到的⼆进制再转换为⼗进
制输出。0001
^0010
----------------
0011=>3
按位左位移<<
<
0001<<1====>0010
按位右位移>>
>>n表⽰⼆进制数右移n位,空位补0,保留符号位。2>>1====>1
0010>>1====>0001
⽆符号按位右位移>>
>>n表⽰⼆进制数右移n位,空位补0,不保留保留符号位。
--需求:计算2*8的结果
计算机中的乘法运算和我们数学中的乘法运算是类似的,不同的是将2和8换算成⼆进制再进⾏数学乘法运算。
最后再换成成⼗进制数输⼊,即16。这种乘法算法效率是很复杂,即效率⽐较低。
其实乘法可以使⽤左位移,因为左位移就相当于乘以2的位移次幂。所以这⾥的2*8可以使⽤2<<3来计算,⽽且位移运算没有进⾏任何算术
运算,只是将⼆进制串整体进⾏位置挪动,效率是⽐计算机乘法运算要⾼的。除法(右位移)类似。
publicstaticvoidmain(String[]args){
n(2<<3);
}
要想使⽤位移运算来替代原始乘法运算,乘数必须是2的次幂,即1、2、4、8、16....2^n。
如2*5。
publicstaticvoidmain(String[]args){
n(5<<1);
}
只要有⼀个乘数是2的次幂即可,如果两个乘数都不是2的次幂,那么只能使⽤底层乘法运算进⾏计算。
因此,在进⾏乘除法运算的时候,优先考虑使⽤位移运算。
9.运算符的优先级
实际开发过程中,表达式有可能是多种运算符混合运算,此时要搞清楚运算符的优先级。
总结:=优先级最低,()优先级最⾼想让谁先计算就加()。
10.字符串连接符
+两边的表达式如果都是数值型(类似数值型),表⽰加法操作;如果+两边的表达式有⼀个为字符串,+就会把另外⼀个操作数转为字符串后
连接第⼀个操作数。
11.总结
java运算符:[1]按照操作数的数⽬分类:单⽬、双⽬、三⽬运算。
[2]按照运算符的功能分类:赋值、算术、关系、逻辑、条件、位运算。
[3]按照功能分类记忆会⽐较容易。
赋值运算符:[1]赋值运算符有:=、+=(递增)、-=(递减)、*=(倍增)、/=、%=。
[2]赋值运算符将=号右边的内值存⼊到=号左边的变量空间中去。
算术运算符:[1]算术运算符有:+、-、*、/、%、++、--。
[2]/在java中表⽰整除,整数和整数运算得到的⼀定是整数;只要有⼩数参与整除/得到的⼀定是⼩数。
[3]/中被除数不能为0。
[4]%取余(求模),模谁就不会超过谁!e.g:5%2结果是1
[5]++/--在前,先+1/-1,后运算。
[6]++/--在后,先运算,后+1/-1。
关系运算符:[1]关系运算符有:>、>=、
[2]关系运算符⽤于⽐较⼤⼩关系,以及是否是某个类的⼦类。
[3]⼩数不能⽤于关系运算符的⽐较,因为⼩数的精确程度不准确,如0.1不等于1.0/10。
逻辑运算符:[1]逻辑运算符有:逻辑与&、逻辑或|、逻辑⾮!、逻辑异或^、短路与&&、短路或||。
[2]逻辑与&和短路与&&都需要两侧表达式的boolean值全为true最终结果才为true,不同之处在于判断的范围。
[3]逻辑与&会判断所有表达式的boolean值,⽽短路与&&,当第⼀个表达式的boolean值为fal时,就终⽌判断后续表达式的boolean
值,所以短路与&&在效率上会⽐逻辑与&有⼀些优势,但不是绝对的,前提条件是第⼀个表达式的boolean值为fal.
[4]逻辑或|和短路或||都是只需⼀则表达式的boolean值为true最终结果就为true,不同之处在于判断的范围。
[5]逻辑或|会判断所有表达式的boolean值,⽽短路或||,当第⼀个表达式的boolean值为true时,就终⽌判断后续表达式的boolean值,
所以短路或||在效率上会⽐逻辑或|有⼀些优势,但不是绝对的,前提条件时第⼀个表达式的boolean值为true。
[6]逻辑异或^,当两侧表达式的boolean值不同时最终结果才为true,若两侧表达式的boolean值都相同最终结果为fal。
[7]逻辑⾮!,会将表达式的boolean值取反,即由true变为fal,由fal变为true。
位运算:[1]位运算符有:按位与&、按位或|、按位异或^、按位取反~,按位左位移<>、⽆符号按位右位移>>>。
[2]位运算是对⼆进制数计算的。
[3]按位与&,⾸先将按位与&两侧的⼗进制数转化为⼆进制数,接着对应位置进⾏判断,同为1才为1,否则为0,最后将得到的⼆进制串
再转化为⼗进制数输出。
[4]按位或|,⾸先将按位或|两侧的⼗进制数转化为⼆进制数,接着对应位置进⾏判断,只要有1即为1,全为0才为0,最后将得到的⼆进制
串转化为⼗进制数输出。
[5]按位异或^,⾸先将按位异或^两侧的⼗进制数转化为⼆进制数,接着对应位置进⾏判断,只有当⼀侧为0,另⼀侧为1时才为1,否则为
0,最后将得到的⼆进制串转化为⼗进制数输出。
[6]按位取反~,按位取反~需要⽤到原码、反码和补码的知识。
[7]按位左位移<
[8]按位右位移>>,⾸先将⼗进制数转化为⼆进制数,然后右位移,如按位右位移2位,那么就右位移两次,并且⾼位右0填充,直接抛弃低
位,相当于在原⼗进制数的基础上除以2的位移位置次幂,注意符号位是保留的,即最左的bit位是不变的,并且移动的位数超过了最⼤位数
时会对其取模再移位。
[9]⽆符号按位右位移>>>,⾸先将⼗进制数转化为⼆进制数,然后右位移,如⽆符号按位右位移2位,那么就整体右位移两位,并且直接⽤
0填充⾼位,直接抛弃低位,注意符号位是不保留的,即最左的bit位直接由0填充,并且移动的位数超过了最⼤位数时会对其取模再移位。
[10]在进⾏乘除法运算时,优先考虑位运算。
[11]&和&&的区别
&可以视为逻辑运算,也可以视为位运算,⽽&&只能视为逻辑运算。如果两个符号都视为逻辑运算符来使⽤的时候会有如下区别:1、逻辑
与&只有前后两个条件都是true时,最终结果才为true。2、短路与&&正常情况下和逻辑与&的执⾏结果是⼀致的,即前⾯的条件为true。
只有当短路与&&前⾯的条件为fal的时候,才会发⽣短路,即最终结果为fal。
字符串连接符+:[1]如果+两边的表达式都是数值型(类数值型),表⽰加法运算。
[2]如果+两边的表达式有⼀个为字符串,那么+就会把另外⼀个操作书转换为字符串后连接改字符串。
运算符的优先级问题:[1]赋值运算符的优先级最低,⼩括号()的优先级最⾼。
[2]想让谁先运算就给谁加⼩括号()。
本文发布于:2022-12-11 14:12:13,感谢您对本站的认可!
本文链接:http://www.wtabcd.cn/fanwen/fan/88/86122.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |