c语言如何使用mq中间件(cqh-运算符)
内容导视:
- 算术运算符
- 赋值运算符
- 关系运算符
- 逻辑运算符
- 条件运算符
- 按位运算符
- 移位运算符
- 运算符优先级
加油,还不算晚。
5.1 算术运算符内容导视:
- 四则运算
- 求余数
- 自增自减
这个不用过多介绍,分别是加减乘除,操作数是数值类型或者能自动拆箱成数值类型,与初等数学一致,直接使用即可。
int a = 5;
int b = 2;
int add = a b;// 7
int sub = a - b;// 3
int mult = a * b;// 10
int divide = a / b;// 2
注意 int 类型只能保存整数,会被削去小数部分。
此外 “ ” 除了能够计算加法,操作数可以是 String 类型,用于拼接字符串,只要有一边操作数是 String 类型,则最终结果也是 String 类型,之前已经说过:
System.out.println(100 2 "字符串" 3 * 8);
“102字符串24”;从左至右,遇到字符串就拼接,拼接后还是字符串;乘法优先于加法。
5.1.2 求余数求余数也称取模。得到的余数一定小于除数。
如 10 % 3 = 1、11 % 3 = 2、12 % 3 = 0;
int i = 11 % 4;
11 除以 4,商为 2,余数为 3;所以 i = 3。
% 的本质
a % b = a - a / b * b
知道了上面的式子,自己试着算一下吧:
System.out.println(-10 % 3);
System.out.println(10 % -3);
System.out.println(-10 % -3);
计算结果如下:
-10 % 3 = -10 - (-10) / 3 * 3
= -10 - (-3) * 3
= -1
10 % -3 = 10 - 10 / (-3) * (-3)
= 10 - (-3) * (-3)
= 1
-10 % -3 = -10 - (-10) / (-3) * (-3)
= -10 - 3 * (-3)
= -1
是让变量保存的值,自加一。
int i = 10;
i ;
System.out.println(i);// i = 11
int i = 10;
i;
System.out.println(i);// i = 11
放在变量前后的区别
放在变量前:
int i = 10;
int j = i;
System.out.println(j);// j = 11
等价于
int i = 10;
i = (int)(i 1);// 先自加一,后赋值
int j = i;
System.out.println(j);// j = 11
放在变量后:
int i = 10;
int j = i ;
System.out.println(j);// j = 10
int i = 10;
int j = i;// 先返回值,后自加一
i = (int)(i 1);
System.out.println(j);// j = 10
结论:
当 出现在变量前,先自加一,再返回值;所以 i 自加一等于 11,再赋值给 j,j 为 11;
当 出现在变量后,会先返回值,再自加一;把 i 赋值给 j 即 10,再 i 自加 1。
反正 i 一定是 11;使用 或 -- 时,不会改变运算结果的类型。
例如:
byte b = 1;
b = b 1;
会报错从 int 转成 byte 可能会有损失;
换成如下会自动强转成 byte 类型,但是要注意别超了 byte 的取值范围,否则强转后会有精度损失。
byte b = 127;
b ;//b = -128
-- 同理:
int i = 3;// i = 3
int j = i--;// j = 3、i = 2
int z = --j;// j = 2、z = 2
i = 2、j = 2、z = 2。
建议 、--,最好单独一行,很直观地就能判断是加一或减一,放在表达式中分不清谁前谁后容易让人困扰。
思考
int i = 10; i = i; System.out.println(i);
这道题,不是那么好讲,使用 Javap -v 反编译(先弹出栈顶的数)看看就行,不用了解,没有人会这么用的。
什么是栈顶,就是容器最上面的一个元素。打个比方,一个空羽毛球筒,现在放入羽毛球 a(称为入栈),此时栈顶是羽毛球 a;现在又放入一个羽毛球 b,b 把 a 压住了,b 在 a 的上面,此时 b 就是栈顶;想要拿出 a,必须先拿出 b(称为弹栈,把最上面的元素取出来),这就是后进先出、先进后出。
对代码进行反汇编,反编译后得到的结果:
0: bipush 10 // 将 10 压入操作数栈中 {10} 2: istore_1 // 从操作数栈中弹出一个数也就是 10,存储到第 2 个变量槽 {} {?,10} 3: iinc 1, 1 // 第 2 个变量槽的值自增 1 {} {?,11} 6: iload_1 // 将局部变量表的第 2 个变量槽中的值复制到操作数栈顶 {11} {?,11} 7: istore_1 // 将 11 取出,存储到第 2 个变量槽中 {} {?,11}
人话就是:将 10 赋给变量 i,i 自增一为 11,将 11 赋给 i。
下一道题:
int i = 10; i = i ; System.out.println(i);
反编译部分节选:
// int i = 10; 0: bipush 10 // 将 10 压入操作数栈 {10} 2: istore_1 // 将 10 弹出存储到第 2 个变量槽 {} {?,10} 3: iload_1 // 将第 2 个变量槽的值压入操作数栈 {10} {?,10} // i ; 4: iinc 1, 1 // 第 2 个变量槽的值自增 1 {10} {?,11} // i = 10; 7: istore_1 // 将 10 弹出存储到第 2 个变量槽 {} {?,10} 8: return
可以看到 10 被存储到操作数栈,但没有先赋给 i,而是 i 自增为 11 后,再将 10 赋给 i。
例 3:
byte b = 1; byte b1 = b ;// b1 = 1,b = 2 byte b2 = --b;// b = 1,b2 = 1 System.out.println(b);// 1 System.out.println(b1);// 1 System.out.println(b2);// 1
反编译部分节选:
5.2 赋值运算符
// byte b = 1; 0: iconst_1 # 将 1 压入栈中 {1} 1: istore_1 # 弹栈,存储到第 2 个变量槽中 {} {?,1} // b1 = b, b = (byte)(b 1); 2: iload_1 # 将第 2 个变量槽的值压入操作数栈 {1} {?,1} 3: iload_1 # 将第 2 个变量槽的值压入操作数栈 {1,1} {?,1} 4: iconst_1 # 将 1 压入栈中 {1,1,1} {?,1} 5: iadd # 取出栈中最上面两个值相加,并将结果 2 压入栈中 {2,1} {?,1} 6: i2b # 将 int 类型的值转为 byte,然后又扩展至 int 类型压入栈中 {2,1} {?,1} 7: istore_1 # 弹栈,存储到第 2 个变量槽中 {1} {?,2} 8: istore_2 # 弹栈,存储到第 3 个变量槽中 {} {?,2,1} // b = (byte)(b - 1), b2 = b; 9: iload_1 # 将第 2 个变量槽的值压入栈中 {2} {?,2,1} 10: iconst_1# 将 int 类型的常量 1 压入栈中 {1,2} {?,2,1} 11: isub # 取出栈中最上面两个值相减:2 - 1,并将结果 1 压入栈中 {1} {?,2,1} 12: i2b # 将 int 类型的值转为 byte,... {1} {?,2,1} 13: istore_1# 弹栈,存储到第 2 个变量槽 {} {?,1,1} 14: iload_1 # 将第 2 个变量槽的值压入栈中 {1} {?,1,1} 15: istore_3# 弹栈,存储到第 4 个变量槽 {} {?,1,1,1} 16: return # 结束。
内容导视:
5.2.1 基本赋值运算符
- 基本赋值运算符
- 扩展赋值运算符
之前用过很多次了,通过 “=” 把值赋给变量,完成值传递。
int a = 10;// 10 被赋给了 int 类型的 a
5.2.2 扩展赋值运算符
int j = 10; int i = j;// j 保存的 10 被赋给了 int 类型的 i
扩展赋值运算符: =、-=、*=、/=、%=、...
只要学会了 =,其它触类旁通。
int x = 5; x = 2;// x = 7
相当于将自保存的值加 2:
int x = 5; x = (int)(x 2);// x = 7
使用扩展运算符,不会改变运算结果类型,与 一样, 就等同于 = 1。
看看下面的 i 的值为多少?
byte i = 8; i *= 2;
i = (byte)(i * 2) = 16。
例 2:
byte b = 64; b *= 2;
b = (byte)(b * 2) = (byte)128 = -128;
例 3:
byte b = 23; b %= 2;
b = (byte)(b % 2) = 1;
例 4:
byte b = 13; b /= 2;
b = (byte)(13 / 2) = 6;
5.3 关系运算符就是判断对错,得到一个结果。结果为真,返回 true,假:false。
使用的符号都是英文半角符号,字符之间没有空格。
!= != ! = 都错。
内容导视:
5.3.1 数字比较运算符
- 数字比较运算符
- 判等运算符
<、<=、>、>=,要求运算符两边是数值类型,或者可以自动拆箱为数值类型,得到的布尔字面量使用 boolean 类型的变量接收。
boolean result1 = 6 > 3; boolean result2 = 9 < 6; System.out.println(result1);// true System.out.println(result2);// false
特殊情况
5.3.2 判等运算符
- 如果有一边操作数是 NaN,则结果就是 false。
- Infinity 是正无穷大,大于所有有穷值,-Infinity 是负无穷大,小于所有有穷值。
分为 == 和 !=,对应等于和不等于。[1]
数值类型的判等
当两边的操作数都是数值类型,或者其中之一是数值类型,且另一个可以自动拆箱转为数值类型,按数值大小比较。
System.out.println(5 == 5);// true,5 等于 5,返回 true System.out.println(5 == new Integer(5));// true,Integer 自动拆箱为 5 System.out.println(5 != 4);// true System.out.println('a' == 95);// false,'a' 对应十进制整数为 97
当判等运算符的两边之一是 NaN,则 == 结果为 false,!= 结果为 true,换言之 NaN 不等于任何数,包括它自己。如果 x != x 为 true,则 x 的值为 NaN。
final double NaN = 0.0 / 0.0; System.out.println(NaN == NaN);// false System.out.println(NaN != NaN);// true System.out.println(NaN == 3);// false System.out.println(NaN != 3);// true
Infinity 除了与自己比较时,== 为 true,与其它值比较,== 都为 false。
布尔类型的判等
当两边的操作数都是布尔类型,或者其中之一是布尔类型,且另一个可以自动拆箱转为布尔类型,如果两边都是 true 或者 false,则 == 结果为 true,否则为 false。
如果两边都是 true 或者 false,则 != 结果为 false,否则为 true。
System.out.println(true == true);// true System.out.println(false == false);// true System.out.println(true == false);// false System.out.println(true != true);// false System.out.println(false != false);// false System.out.println(true != false);// true
引用类型的判等
两边的操作数都是引用类型,两边操作数的类型相同或是父子类型。
如果两边的操作数的值都为 null,或都引用相同的对象,则 == 结果为 true,否则为 false。
如果两边的操作数的值都为 null,或都引用相同的对象,则 != 结果为 false,否则为 true。
String str1 = null; Object str2 = null; System.out.println(str1 == str2);// true System.out.println("hello" == "hello");// true System.out.println("hello1" == "hello");// false
关于 String 类型的比较可查看 “2.3.5 解析 -> 字符串类型字面量解析”,其它引用类型的比较等到面向对象吧。
[1] 注意别把 “==” 与 “=” 混用了。我知道在日常生活中,使用 “=” 判断是否相等,但是在程序里 “=” 是用来赋值的,“==” 才是用来判断是否相等。
我举个例子,if 旁边的括号中的值只允许为 boolean 类型,当值为 true 时,才会执行 if {} 中的语句。
int i = 4; if (i = 5) { System.out.println("Hello"); }
假如你的原意是想 i 等于 5 时,就输出 “Hello”,但是由于你使用的是单等号,代表赋值,此时的 i = 5,所以原意成了
int i = 4; if (5) { System.out.println("Hello"); }
在 Java 中,正好 boolean 类型不能参与转换,所以编译时直接报错,你可以及时发现,但不是次次都是这么好运气。
如下:
boolean b1 = false; if (b1 = true) { System.out.println("Hello");// Hello } System.out.println(b1);// true
原意是当 b1 等于 true 时,输出 “Hello”,但是你的意图被扭曲了,这只是你不小心丢了一个等号而已。
在 JDK 源码中,经常看到赋值、判断混合在一起,令人头晕,完全可以单独提取出来,可读性会好些。
你的原意可能如下:
boolean b1 = false; if (b1 == true) { System.out.println("Hello"); } System.out.println(b1);// false
说了这么多,只为说一句:判断两个值是否相等,请用 “==”。但是我私底下或写注释时,还是习惯用单等号代表两个值相等。
5.4 逻辑运算符内容导视:
- 与
- 或
- 非
- 异或
前提:逻辑运算符的两边要求都是布尔类型,且最终的结果也是布尔类型,下面是我高中时记的口诀:
and 与(&):一假为假
or 或(|):一真为真
not 非(!):真即假,假即真
xor 异或(^):不同为真,相同为假
5.4.1 逻辑与a & b:当 a 和 b 同时为 true 时,结果才为真,否则为 false。
boolean b1 = 5 > 3; boolean b2 = 8 < 9; System.out.println(b1 & b2);// true
翻译成人话:5 大于 3 且 8 小于 9,命题为真。
需要注意的是,不同的运算符优先级不同,优先级高的先运算。之前通过乘法与加法的混合运算中就能看出来乘法优先。
思考如下输出结果:
boolean b1 = 1 < 0; boolean b2 = 79 > 99; boolean b3 = false; System.out.println(b1 & b2 == b3);
b1、b2、b3 都为 false;b1 & b2 为 false,false == b3,所以结果为 true?
但你没有想到 “==” 的优先级高于 “&”,所以是 b2 == b3 先运算结果为 true,b1 & true,结果为 false。
上面的一句相当于:
System.out.println(b1 & (b2 == b3));// false
那该怎么办?扭曲了原意!可以加小括号提升优先级:
System.out.println((b1 & b2) == b3);// true
短路与
&&(short circuiting)相比于逻辑与,效率更高:如果整个表达式结果已经确定,就停止并返回结果,剩下式子不再执行与判断。
什么意思?
一假为假,当左边的值为 false 时,还需要去执行去判断右边吗?完全可以推出结果为 false。
int x = 3; System.out.println((x < 2) & ( x > 3)); System.out.println(x);// 4
int x = 3; System.out.println((x < 2) && ( x > 3)); System.out.println(x);// 3
x < 2 为 false,那么整个式子已经可以确定为 false,不需要再判断。通过上面的例子可以看出,短路与并没有去执行右半部分的 x,所以 x 的结果不变,还是为 3。利用短路可以省去不必要的计算,从而提高效率。
5.4.2 逻辑或a | b:当 a 和 b 同时为 false 时,结果才为 false,否则为 true。
System.out.println(8 < 1 | 9 > 3);// true
命题:8 小于 1 或者 9 大于 3,命题为真。
与 & 一样的是,| 也有对应的 ||。
短路或
如果整个表达式的结果已经确定,后面不再执行判断。
int x = 3; System.out.println(8 < 9 | x == 8); System.out.println(x);// 4
int x = 3; System.out.println(8 < 9 || x == 8); System.out.println(x);// 3
一般我们使用的是短路与、短路或,我几乎没有看见单个的,除非你想把所有的式子都执行一遍。
5.4.3 非!a:对 a 取反;a 为 true,则结果为 false;a 为 false,结果为 true。
System.out.println(!(3 < 5));// false
3 < 5 为 true,再取反为 false。
5.4.4 逻辑异或a ^ b:当 a 不等于 b,结果为 true,否则为 false。
System.out.println(8 < 9 ^ 9 > 3);// false System.out.println(8 < 9 != 9 > 3);// false
8 < 9 为 true,9 > 3 为 true,它们相等,所以为 false。
很少见,一般使用 !=。
5.5 条件运算符算是条件语句的简化版吧,可以根据表达式的真假返回不同的值。
条件运算符又称三目运算符、三元运算符,因为有三个操作数。[1]
语法:布尔值 ? 值1 : 值2;
当布尔值为 true,返回值 1;为 false,返回值 2。
boolean isBoy = true; char zhangSan = isBoy ? '男' : '女'; System.out.println(zhangSan);// 男
double scope = 99.5; String evaluate = scope < 60 ? "不及格" : "及格"; System.out.println(evaluate);// 及格
很明显 scope 小于 60 为 false,所以返回值2,“及格”。
三目运算符与之后讲的 if-else 类似,但是它是有返回结果的,而 if-else 没有。
[1] 与此对应的二元运算符(如 !=、==、<、 ...)、一元运算符( 、--)。
5.6 按位运算符内容导视:
- 按位与
- 按位或
- 按位异或
- 按位取反
前提:要求操作数是整数类型。
按位运算符主要用来对操作数二进制的位进行运算。按位运算表示按每个二进制位(bit)进行计算,其操作数和运算结果都是整数类型。
除按位取反(一元运算符)外,其它按位运算符可以与 “=” 组合成扩展赋值运算符。如 &=,x &= 2; 相当于 x = (?)(x & 2);
? 是 x 的类型。
5.6.1 按位与参与运算的数字,低位对齐,高位不足的补零,如果对应的二进制位同时为 1,那么结果才为 1,否则为 0。因此,任何数与 0 进行按位与运算,其结果都为 0。
int x = 2 & 3;
首先写下它们的补码 2 的补码是 00000000 00000000 00000000 00000010 3 的补码是 00000000 00000000 00000000 00000011 比较结果: 00000000 00000000 00000000 00000010
所以 x = 2。
5.6.2 按位或参与运算的数字,低位对齐,高位不足的补零。如果对应的二进制位只要有一个为 1,那么结果就为 1,否则为 0。因此,任何数与 0 进行按位与运算,其结果都为那个数自己。
int x = 3 | 4;
3 的补码:... 00000011 4 的补码:... 00000100 比较结果:... 00000111
x = 7。
5.6.3 按位异或参与运算的数字,低位对齐,高位不足的补零,如果对应的二进制位不同时,结果为 1,否则为 0。
int x = 9 ^ 12;
9 的补码:... 00001001 12 的补码:... 00001100 比较结果: ... 00000101
x = 5。
特性
x ^ y ^ y = x;
x ^ y ^ x = y;
int x = 9; int y = 15; int a = x ^ y ^ y; int b = x ^ y ^ x;
9 的补码: 00001001 15 的补码: 00001111 9 ^ 15: 00000110 (9^15)^15:00001001 (9^15)^9: 00001111
可以利用此特性,完成两整数交换:
5.6.4 按位取反
int a = 3; int b = 9; a = a ^ b;// a = 3 ^ 9 b = a ^ b;// b = 3 ^ 9 ^ 9 = 3 a = a ^ b;// a = 3 ^ 9 ^ 3 = 9
只对一个操作数进行运算,将操作数的二进制中的 1 改为 0,0 改为 1。
byte b = ~0;
0 的补码:00000000 00000000 00000000 00000000 取反: 11111111 11111111 11111111 11111111 是 -1 的补码,所以 b = -1;
例 2:
byte b = ~1;
1 的补码:00000000 00000000 00000000 00000001 取反: 11111111 11111111 11111111 11111110 是 -2 的补码,b = -2;
例 3:
b = ~ -128;
-128 的原码:10000000 00000000 00000000 10000000 反码: 11111111 11111111 11111111 01111111 补码: 11111111 11111111 11111111 10000000 取反: 00000000 00000000 00000000 01111111 是 127 的补码,b = 127;
推测:~x = -x - 1;
引子:
5 (-6) 对应的补码为 5 的补码 -6 的补码 = 00000101 11111010 = 11111111 所以补码 11111111 对应的值是 5 (-6) = -1
证明:* 代表未知,# 代表对 * 取反后的二进制位。
设正数 x,补码、原码、反码为:0******* ~x = 1####### 现在只要求补码 1####### 对应的值即可 -x - 1 = -x (-1) -x 的原码是 1******* -> 反码 1####### -> 补码 1####### 00000001 -1 的原码是 10000001 -> 反码 11111110 -> 补码 11111111 -x (-1) 对应的补码为: = 1####### 00000001 11111111 = 1####### (00000001 11111111) = 1####### 00000000 = 1####### 所以补码 1####### 对应的值是 -x - 1
设负数 x,原码为 1*******,反码 1#######,补码 1####### 00000001 ~x = 11111111 - (1####### 00000001) = 0******* - 00000001 现在只要求补码 0******* - 00000001 对应的值即可 -x 是正数,原码、反码、补码为 0******* -x - 1 = -x (-1) 对应的补码为: = 0******* 11111111 = 0******* 11111111 00000001 - 00000001 = 0******* 00000000 - 00000001 = 0******* - 00000001 0******* - 00000001 对应的值是 -x - 1
当 x 为 0 和 -128 时,取反也是 -x - 1。
5.7 移位运算符移位运算符主要用来对操作数二进制的位进行移动,其操作数和运算结果都是整数类型。
可以与 “=” 组合成扩展赋值运算符。
内容导视:
5.7.1 左移位运算符
- 左移位运算符
- 有符号右移位运算符
- 无符号右移位运算符
左移位运算符为 <<,其运算规则是:按二进制形式把所有的数字向左移动对应的位数,高位移出(舍弃),低位的空位补零。
byte b = 4 << 2;
4 的补码:00000000 00000000 00000000 00000100 左移两位:00000000 00000000 00000000 00010000 是 16 的补码,b = 16;
例 2:
byte b = 3 << 4;
3 的补码:00000000 00000000 00000000 00000011 左移四位:00000000 00000000 00000000 00110000 是 48 的补码,b = 48;
规律:x << n = x * 2 ^ n。
5.7.2 有符号右移位运算符对于正数, >> 会把所有的位右移,并在最前面补 0; 对于负数, >> 会把所有的位右移,并在最前面补 1。
byte b = 3 >> 1;
3 的补码 00000000 00000000 000000000 00000011 右移一位:00000000 00000000 000000000 00000001 是 1 的补码,所以 b = 1;
例 2:
byte b = -4 >> 2;
-4 的补码:11111111 11111111 11111111 11111100 右移 2 位:11111111 11111111 11111111 11111111 是 -1 的补码,所以 b = -1;
规律:x >> n = x / 2 ^ n。
我有时使用 x >> 1 代替 x / 2 的操作。
如 7 >> 1 = 7 / 2 = 3;
int start = 3; int end = 9; int mid1 = (start end) / 2; int mid2 = start (end - start) / 2; int mid3 = start ((end - start) >> 1); System.out.println(mid1);// 6 System.out.println(mid2);// 6 System.out.println(mid3);// 6
注意移位运算符没有算术运算符优先级高,所以需要加小括号提升优先级,否则 int mid3 = start (end - start) >> 1 = 3 6 >> 1 = 9 >> 1 = 4;
5.7.3 无符号右移位运算符将所有位数右移,最前面补 0。
byte b = (byte)(-4 >>> 2);
-4 的补码:11111111 11111111 11111111 11111100 右移 2 位:00111111 11111111 11111111 11111111 是 1073741823 的补码,超出 byte 的取值范围 截去前面 3 个字节得到:11111111 是 -1 的补码,所以 b = -1;
例 2:
int i = -8 >>> 5;
-8 的补码:11111111 11111111 11111111 11111000 右移 5 位:00000111 11111111 11111111 11111111 是 134217727 的补码,i = 134217727;
例 3:
773 = 0x0305;使用两个字节 0x03、0x05 保存。
byte b1 = 0x03; byte b2 = 0x05; System.out.println(b1 << 8 | b2);
5.8 运算符优先级
3 的补码: 00000000 00000000 00000000 00000011 左移 8 位:00000000 00000000 00000011 00000000 5 的补码: 00000000 00000000 00000000 00000101 按位或: 00000000 00000000 00000011 00000101 是 773 的补码,输出 773
优先级高的先运算。
优先级从高到低 . () -- ~ ! 单目运算符 * / % 算术运算符 - << >> >>> 位移运算符 < > <= >= instanceof 比较运算符 == != 逻辑运算符 & ^ | && || ? : 三目运算符 = *= /= %= 赋值运算符 = -= <<= >>= >>>= &= ^= |=
例如:int a = 1 2 * 1; 先算乘法,接着加法,最后赋值。
int a = 1; int b = 2; int c = 3; int d = 4; int e = 5; boolean f = true; boolean g = false; boolean h = g & f == e < d << c b / a;
5.x 总结回顾
g & f == ? 先算 f == ? f == e < ? 先算 e < ? e < d << ? 先算 d << ? d << c ? 先算 c ? c b / ? 先算 b / ? b / a 先算 a,先 ,a = 2,后返回值 2 b / 2 = 1; c 1 = 4; d << 4 = 64; e < 64 为 true f == true 为 true g & true 为 false 所以 h = false
使用 、--、 = 等扩展赋值运算符时不会改变运算结果类型。(使用了强制转换运算符,可能会造成精度损失)
判断两个基本类型的值是否相等请用 “==”。
逻辑运算符中一般使用短路与、短路或。
一定要注意不同运算符之间的优先级,最好亲自测一下,看是否与预期一致,或者直接加小括号提升优先级。
5.y 课后习题5.1 double i = 5 / 2; 中的 i 的值为?
5.2 输出什么?
1)
String s = "张三"; int i = 3; System.out.println(s i * 2 "b");
2)
int x = 5; int y = 5; System.out.println( x < 6); System.out.println(y < 6); System.out.println(y);
3)
int x = 10; int a = x (x ); int b = x ( x); System.out.println(a); System.out.println(b); System.out.println(x);
4)
int i = 34; int j = i--; int z = --i; System.out.println(i); System.out.println(j); System.out.println(z);
5)
int i = 2; int j = 2 i ; System.out.println(i); System.out.println(j);
6)
boolean b = false; System.out.println(b = true); System.out.println(b == false);
7)
int x = 9; int y = 12; int z = x < y ? x y : x - y; System.out.println(z);
8)
int a = 10; int b = 99; int result = a > b ? a : b--; System.out.println(result); System.out.println(a); System.out.println(b);
5.3 利用三目表达式求出三个数之间的最大数。
5.4 利用所学知识求出 33 天是多少个星期零几天?
5.5 3 / 9 * (242.2 - 100) 的结果是什么?
5.6 下面代码输出什么?
1)
boolean x = true; boolean y = false; byte num = 2; if ((num == 2) && (y = true)) {num ;} if ((x = false) || ( num == 5)) {num ;} System.out.println(num); System.out.println(x); System.out.println(y);
2)
int i = 342; int b = i i; System.out.println(b);
3)
5.z 习题答案
int i = 342; int b = i i; System.out.println(i); System.out.println(b);
5.1 double i = 5 / 2; 中的 i 的值为?
5 / 2 = 2,再自动升级成 double 类型,所以 i = 2.0。
5.2 输出什么?
1)
String s = "张三"; int i = 3; System.out.println(s i * 2 "b");
"张三" 3 * 2 "b"
先算乘法,所以输出 张三6b
2)
int x = 5; int y = 5; System.out.println( x < 6); System.out.println(y < 6); System.out.println(y);
先 ,x = 6,再判断,输出 false;先判断 5 < 6,输出 true,再 ,y = 6,输出 6。
3)
int x = 10; int a = x (x ); int b = x ( x); System.out.println(a); System.out.println(b); System.out.println(x);
a = 10 10 = 20,x 后为 11;b = 11 12 = 23,x 为 12。输出 20、23、12。
4)
int i = 34; int j = i--; int z = --i; System.out.println(i); System.out.println(j); System.out.println(z);
j = 34,后--,i = 33;先--,i = 32,z = 32。输出 32、34、32。
5)
int i = 2; int j = 2 i ; System.out.println(i); System.out.println(j);
j = 2 2 = 4,随后 i 自加一为 3,输出 3、4
6)
boolean b = false; System.out.println(b = true); System.out.println(b == false);
b = true,输出 b 的值:true。true 等于 false 为假,输出 false。
7)
int x = 9; int y = 12; int z = x < y ? x y : x - y; System.out.println(z);
9 < 12 为 true,返回 x y = 21,赋给 z,输出 21。
8)
int a = 10; int b = 99; int result = a > b ? a : b--; System.out.println(result); System.out.println(a); System.out.println(b);
10 > 99 为 false,返回 b--:先将 b 的值 99 赋给 result,后 b--,b = 98。输出 99、10、98。
5.3 利用三目表达式求出三个数之间的最大数。
先定义三个变量保存数值,先让其中两数比较,返回大值赋给 max1;再让 max1 与剩下的数比较返回大值。
int n1 = 241; int n2 = 324; int n3 = 242; int max1 = n1 > n2 ? n1 : n2; int max2 = max1 > n3 ? max1 : n3; System.out.println(max2);
5.4 利用所学知识求出 33 天是多少个星期零几天?
让 33 除以 7,商就是星期数,余数就是天数。
int day = 33; int week = day / 7; int RemainDay = day % 7; System.out.println(day "天是" week "个星期零" RemainDay "天");
5.5 3 / 9 * (242.2 - 100) 的结果是什么?
因为 3 / 9 = 0,所以结果为 0;要想不偏离原意,请至少把其中一个数转为 double 类型。
5.6 下面代码输出什么?
1)
boolean x = true; boolean y = false; byte num = 2; if ((num == 2) && (y = true)) {num ;} if ((x = false) || ( num == 5)) {num ;} System.out.println(num); System.out.println(x); System.out.println(y);
只有 if () 中为 true,才会执行 {} 中的语句。
直接快进到 if 语句 num == 2: 先判断 num 是否等于 2,为 true 再自加一,num = 3;此时不能断定结果,继续看右边 y = true:给 y 赋值为 true 两边条件都为 true,&& 后的结果为 true,执行 num num = 4 接着看第 2 个 if 语句 x = false:给 x 赋值 false 既然 x 为假,不能断定结果,继续看第 2 个条件 num == 5: 先自加一,num = 5 再判断 num 是否等于 5,为 true 两个条件一假一真,|| 后的结果为 true,执行 num num = 6 输出 6、false、true
2)
int i = 342; int b = i i; System.out.println(b);
先 i,i = 343,再赋值:b = 343 343 = 686。
3)
int i = 342; int b = i i; System.out.println(i); System.out.println(b);
i i 先进行加法运算再自加一 即 342 (i),此时 i 后,i = 343 现在再看右边的 i,先自加一,即 i = 344,再运算 int b = 342 344 = 686 i = 344 输出 344、656
例 1:
int i = 342; i = i i ; System.out.println(i);
先进行加法运算 342 i ,后自加 1,i = 343 先进行加法运算 342 343 后 i 自加 1,i = 344 计算 342 343 = 685 再赋给 i,输出 685
0: sipush 342 {342} 3: istore_3 {} {?,?,?,342} 4: iload_3 {342} {?,?,?,342} 5: iinc 3, 1 {342} {?,?,?,343} 8: iload_3 {342,343} {?,?,?,343} 9: iinc 3, 1 {342,343} {?,?,?,344} 12: iadd {685} {?,?,?,344} 13: istore_3 {} {?,?,?,685}
第 2 个例子:
int i = 342; i = i i; System.out.println(i);
先进行加法运算 342 i,后自加 1,i = 343 i 先自加一,i = 344,再进行加法运算 342 344 = 686 i = 686
第 3 个例子:
int i = 342; i = i i; System.out.println(i);
先自加一,i = 343,得到:343 i 先自加一,i = 344,得到:343 344 = 687 i = 687
像极了茴香豆的“茴”有几种写法,大家看个乐呵就行。
,
免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。文章投诉邮箱:anhduc.ph@yahoo.com