黑马程序员技术交流社区
标题: java 运算符笔记 [打印本页]
作者: 破烂小白 时间: 2015-5-13 14:47
标题: java 运算符笔记
本帖最后由 破烂小白 于 2015-5-13 15:11 编辑
运算符这个东西需要死记。。尤其是位和逻辑运算 刚开始看的时候搞得蒙蒙的。。运算符指明对操作数的运算方式。组成表达式的Java操作符有很多种。运算符按照其要求的操作数数目来分,可以有单目运算符、双目运算符和三目运算符,它们分别对应于1个、2个、3个操作数。运算符按其功能来分,有算术运算符、赋值运算符、关系运算符、逻辑运算符、位运算符和其他运算符。
算术运算就不所了 加减乘除取余 “++”“ --” 递加递减 这些小学的支持很容易理解
赋值运算符 = += -= *= /= %= &= ^= |= <<= >>= 简单的说就是结果传递 也很容易理解
关系运算符 〈 大于〉小于!=不等于 还有大于等于等这些 返回结果只有两种 真或假
逻辑运算符 比较难理解的 建议多写代码联系几遍 关看视频理解是很费劲的 与(&&)、非(!)、或(||)
(&&): x && y 对应于操作 x & y (就是一个判断符 记住判断方式就是了)
但,如果 x是 false, y 不会计算,因为,和操作的结果是 false ,无论 y 的值为。 这被称作为“短路”计算。
<span id="mt6" class="sentence" data-guid="be6d89a137e57e953659b02a8edc00fd" data-source="The conditional-AND operator cannot be overloaded, but overloads of the regular logical operators and operators true and false are, with certain restrictions, also considered overloads of the conditional logical operators." xml:space="preserve"> 不能重载条件“与”运算符,但常规逻辑运算符和运算符 true 与 false 的重载,在某些限制条件下也被视为条件逻辑运算符的重载。
<span class="sentence" data-guid="be6d89a137e57e953659b02a8edc00fd" data-source="The conditional-AND operator cannot be overloaded, but overloads of the regular logical operators and operators true and false are, with certain restrictions, also considered overloads of the conditional logical operators." xml:space="preserve"> 非(!):翻译白话就是 不是的意思呗
或(||):全为真 返回真
1.与(&,&&)和或(|,||)的区别
1.1使用与操作的时候,要求前后几个表达式的内容都是true,最终结果才是true,如果有一个是false,则最终结果就是false;
1.2使用或操作的时候,要求前后几个表达式只要有一个true,则最终结果就是true,如果全都是false,则最终结果才是false;
2.与(&)和短路与(&&)的区别以及或(|)和短路或(||)的区别
这点在初学者中,疑惑的人会比较多
先说与操作:既然与操作要求前后几个表达式的内容都是true的时候最终结果才是true,如果使用短路与,则只要第一个结果是false,则整体结果肯定是false,但是程序在这个时候是不会继续执行下去的,相反,如果不是短路与,即使第一个结果是false,程序依然会执行其他的结果下去,虽然最终结果都是一样,给个例子,清楚一点:
- public class Test1{
- public static void main(String args[]){
- if(10!=10&10/0==0){
- System.out.println("条件满足") ;
- }
- }
- };
复制代码
很显然,10!=10结果是false,但是因为没有使用短路与,程序会继续执行第二个条件结果判断,第二个在程序中显然会发生异常,所以这段代码编译可以通过,但是运行就会报错!
再看一段代码:
public class Test2{
public static void main(String args[]){
if(10!=10&&10/0==0){
System.out.println("条件满足") ;
}
}
};
第一个结果是false,程序就不会再执行下去,所以程序运行是正常的;
接下来说说或(|)和短路或(||)的区别
其实你明白了前面的两个与的区别之后,这个就很简单了
或就是表示前后表达式只要有一个是true,结果就是true,所有的表达式都是false,结果才是false;
短路与表示只要第一个表达式是true,则程序就不会去执行其他的表达式判断,相反,如果不是短路或的话,则即使第一个是true,也会都去执行其他的表达式进行判断- public class Test3{
- public static void main(String args[]){
- if(10==10|10/0==0){
- System.out.println("条件满足") ;
- }
- }
- };
复制代码 显然,这个程序执行会报错,因为程序会去判断每一个表达式,而下面:- public class Test4{
- public static void main(String args[]){
- if(10==10||10/0==0){
- System.out.println("条件满足") ;
- }
- }
- };
复制代码 上面的程序因为第一个表达式就是true,而且采用的是短路或,程序不会再执行下面的判断,所有程序正常运行;
OK, 其实实践出真理 自己打出来多试即便就很容易记住了
作者: 破烂小白 时间: 2015-5-13 15:18
没写完呢。另起一行继续
作者: 破烂小白 时间: 2015-5-13 16:16
本帖最后由 破烂小白 于 2015-5-13 16:20 编辑
位运算符 与(&)、非(~)、或(|)、异或(^)&:双目运算符,运算时均把运算数转换为二进制再做比较,规则:当相同的位上均为1时结果为1,否则结 果为0.如:1010&1101,转为二进制:10001001101&1111110010比较结果为:1000000转为十进制: 64所以1010&1101=64;
| :当两边操作数的位有一边为1时,结果为1,否则为0。如1100|1010=1110
~:0变1,1变0
^:两边的位不同时,结果为1,否则为0.如1100^1010=0110
程序中的所有数在计算机内存中都是以二进制的形式储存的。位运算说穿了,就是直接对整数在内存中的二进制位进行操作。比如,and运算本来是一个逻辑运算符,但整数与整数之间也可以进行and运算。举个例子,6的二进制是110,11的二进制是1011,那么6 and 11的结果就是2,它是二进制对应位进行逻辑运算的结果(0表示False,1表示True,空位都当0处理)。
110
AND 1011
---------------
0010 --> 2
=== 1. and运算 ===
and运算通常用于二进制取位操作,例如一个数 and 1的结果就是取二进制的最末位。这可以用来判断一个整数的奇偶,二进制的最末位为0表示该数为偶数,最末位为1表示该数为奇数。
相同位的两个数字都为1,则为1;若有一个不为1,则为0。
00101
11100
(&;或者and)
----------------
00100
=== 2. or运算 ===
or运算通常用于二进制特定位上的无条件赋值,例如一个数or 1的结果就是把二进制最末位强行变成1。如果需要把二进制最末位变成0,对这个数or 1之后再减一就可以了,其实际意义就是把这个数强行变成最接近的偶数。
相同位只要一个为1即为1。
00101
11100
(|或者or)
----------------
11101
=== 3. xor运算 ===
异或的符号是^。按位异或运算, 对等长二进制模式按位或二进制数的每一位执行逻辑按位异或操作. 操作的结果是如果某位不同则该位为1, 否则该位为0.
xor运算的逆运算是它本身,也就是说两次异或同一个数最后结果不变,即(a xor b) xor b = a。xor运算可以用于简单的加密,比如我想对我MM说1314520,但怕别人知道,于是双方约定拿我的生日19880516作为密钥。1314520 xor 19880516 = 20665500,我就把20665500告诉MM。MM再次计算20665500 xor 19880516的值,得到1314520,于是她就明白了我的企图。
相同位不同则为1,相同则为0。
00101
11100
(^或者xor)
----------------
11001
运算结果
x <- x # y
y <- x @ y
x <- x @ y
执行了第一句后x变成了x # y。那么第二句实质就是y <- x # y @ y,由于#和@互为逆运算,那么此时的y变成了原来的x。第三句中x实际上被赋值为(x # y) @ x,如果#运算具有交换律,那么赋值后x就变成最初的y了。这三句话的结果是,x和y的位置互换了。
加法和减法互为逆运算,并且加法满足交换律。把#换成+,把@换成-,我们可以写出一个不需要临时变量的swap过程(Pascal)。
procedure swap(var a,b:longint);
begin
a:=a + b;
b:=a - b;
a:=a - b;
end;
好了,刚才不是说xor的逆运算是它本身吗?于是我们就有了一个看起来非常诡异的swap过程:
procedure swap(var a,b:longint);
begin
a:=a xor b;
b:=a xor b;
a:=a xor b;
end;
注意:位运算版本的交换两数不适用于一个数的自我交换。也就是说,如果上述程序的“b”改成“a”的话,其结果是变量a变成零。因此,在使用快速排序时,由于涉及到一个数的自我交换,因此如果要在其中使用位运算版的交换两数的话,应该先判断。具体的时间损耗在此略过。
=== 4. not运算 ===
not运算的定义是把内存中的0和1全部取反。使用not运算时要格外小心,你需要注意整数类型有没有符号。如果not的对象是无符号整数(不能表示负数),那么得到的值就是它与该类型上界的差,因为无符号类型的数是用00到$FFFF依次表示的。下面的两个程序(仅语言不同)均返回65435。
var
a:word;
begin
a:=100;
a:=not a;
writeln(a);
end.
如果not的对象是有符号的整数,情况就不一样了,稍后我们会在“整数类型的储存”小节中提到。
=== 5. shl运算 ===
a shl b就表示把a转为二进制后左移b位(在后面添b个0)。例如100的二进制为1100100,而110010000转成十进制是400,那么100 shl 2 = 400。可以看出,a shl b的值实际上就是a乘以2的b次方,因为在二进制数后添一个0就相当于该数乘以2。
通常认为a shl 1比a * 2更快,因为前者是更底层一些的操作。因此程序中乘以2的操作请尽量用左移一位来代替。
定义一些常量可能会用到shl运算。你可以方便地用1 shl 16 - 1来表示65535。很多算法和数据结构要求数据规模必须是2的幂,此时可以用shl来定义Max_N等常量。
=== 6. shr运算 ===
和shl相似,a shr b表示二进制右移b位(去掉末b位),相当于a除以2的b次方(取整)。我们也经常用shr 1来代替div 2,比如二分查找、堆的插入操作等等。想办法用shr代替除法运算可以使程序效率大大提高。最大公约数的二进制算法用除以2操作来代替慢得出奇的mod运算,效率可以提高60%。
作者: 破烂小白 时间: 2015-5-13 16:17
本帖最后由 破烂小白 于 2015-5-13 16:18 编辑
位运算符 与(&)、非(~)、或(|)、异或(^)&:双目运算符,运算时均把运算数转换为二进制再做比较,规则:当相同的位上均为1时结果为1,否则结 果为0.如:1010&1101,转为二进制:10001001101&1111110010比较结果为:1000000转为十进制: 64所以1010&1101=64;
| :当两边操作数的位有一边为1时,结果为1,否则为0。如1100|1010=1110
~:0变1,1变0
^:两边的位不同时,结果为1,否则为0.如1100^1010=0110
程序中的所有数在计算机内存中都是以二进制的形式储存的。位运算说穿了,就是直接对整数在内存中的二进制位进行操作。比如,and运算本来是一个逻辑运算符,但整数与整数之间也可以进行and运算。举个例子,6的二进制是110,11的二进制是1011,那么6 and 11的结果就是2,它是二进制对应位进行逻辑运算的结果(0表示False,1表示True,空位都当0处理)。
110
AND 1011
---------------
0010 --> 2
=== 1. and运算 ===
and运算通常用于二进制取位操作,例如一个数 and 1的结果就是取二进制的最末位。这可以用来判断一个整数的奇偶,二进制的最末位为0表示该数为偶数,最末位为1表示该数为奇数。
相同位的两个数字都为1,则为1;若有一个不为1,则为0。
00101
11100
(&;或者and)
----------------
00100
=== 2. or运算 ===
or运算通常用于二进制特定位上的无条件赋值,例如一个数or 1的结果就是把二进制最末位强行变成1。如果需要把二进制最末位变成0,对这个数or 1之后再减一就可以了,其实际意义就是把这个数强行变成最接近的偶数。
相同位只要一个为1即为1。
00101
11100
(|或者or)
----------------
11101
=== 3. xor运算 ===
异或的符号是^。按位异或运算, 对等长二进制模式按位或二进制数的每一位执行逻辑按位异或操作. 操作的结果是如果某位不同则该位为1, 否则该位为0.
xor运算的逆运算是它本身,也就是说两次异或同一个数最后结果不变,即(a xor b) xor b = a。xor运算可以用于简单的加密,比如我想对我MM说1314520,但怕别人知道,于是双方约定拿我的生日19880516作为密钥。1314520 xor 19880516 = 20665500,我就把20665500告诉MM。MM再次计算20665500 xor 19880516的值,得到1314520,于是她就明白了我的企图。
相同位不同则为1,相同则为0。
00101
11100
(^或者xor)
----------------
11001
运算结果
x <- x # y
y <- x @ y
x <- x @ y
执行了第一句后x变成了x # y。那么第二句实质就是y <- x # y @ y,由于#和@互为逆运算,那么此时的y变成了原来的x。第三句中x实际上被赋值为(x # y) @ x,如果#运算具有交换律,那么赋值后x就变成最初的y了。这三句话的结果是,x和y的位置互换了。
加法和减法互为逆运算,并且加法满足交换律。把#换成+,把@换成-,我们可以写出一个不需要临时变量的swap过程(Pascal)。
- procedure swap(var a,b:longint);
- begin
- a:=a + b;
- b:=a - b;
- a:=a - b;
- end;
复制代码
好了,刚才不是说xor的逆运算是它本身吗?于是我们就有了一个看起来非常诡异的swap过程:
- procedure swap(var a,b:longint);
- begin
- a:=a xor b;
- b:=a xor b;
- a:=a xor b;
- end;
复制代码
注意:位运算版本的交换两数不适用于一个数的自我交换。也就是说,如果上述程序的“b”改成“a”的话,其结果是变量a变成零。因此,在使用快速排序时,由于涉及到一个数的自我交换,因此如果要在其中使用位运算版的交换两数的话,应该先判断。具体的时间损耗在此略过。
=== 4. not运算 ===
not运算的定义是把内存中的0和1全部取反。使用not运算时要格外小心,你需要注意整数类型有没有符号。如果not的对象是无符号整数(不能表示负数),那么得到的值就是它与该类型上界的差,因为无符号类型的数是用00到$FFFF依次表示的。下面的两个程序(仅语言不同)均返回65435。
- var
- a:word;
- begin
- a:=100;
- a:=not a;
- writeln(a);
- end.
复制代码
- #include<stdio.h>
- int main()
- {
- unsigned short a=100;
- a=~a;
- printf("%d\n",a);
- return 0;
- }
复制代码
如果not的对象是有符号的整数,情况就不一样了,稍后我们会在“整数类型的储存”小节中提到。
=== 5. shl运算 ===
a shl b就表示把a转为二进制后左移b位(在后面添b个0)。例如100的二进制为1100100,而110010000转成十进制是400,那么100 shl 2 = 400。可以看出,a shl b的值实际上就是a乘以2的b次方,因为在二进制数后添一个0就相当于该数乘以2。
通常认为a shl 1比a * 2更快,因为前者是更底层一些的操作。因此程序中乘以2的操作请尽量用左移一位来代替。
定义一些常量可能会用到shl运算。你可以方便地用1 shl 16 - 1来表示65535。很多算法和数据结构要求数据规模必须是2的幂,此时可以用shl来定义Max_N等常量。
=== 6. shr运算 ===
和shl相似,a shr b表示二进制右移b位(去掉末b位),相当于a除以2的b次方(取整)。我们也经常用shr 1来代替div 2,比如二分查找、堆的插入操作等等。想办法用shr代替除法运算可以使程序效率大大提高。最大公约数的二进制算法用除以2操作来代替慢得出奇的mod运算,效率可以提高60%。
位移 << 带符号左移 >>带符号右移 >>> 无号右移
运算符优先级按优先级从高到低排列如下:[ ] ( ) ++ -- ! ~ instanceof * / % + - << >> >>> <> < = > \ == != &^& & || ? := op= 。
作者: 守株人 时间: 2015-5-13 21:53
写的好详细啊,学习了
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) |
黑马程序员IT技术论坛 X3.2 |