夜光序言:
如果你真很喜欢一个人,
实在放不下的话,
那就继续喜欢吧
或许你会感动ta
或许你会累到放手
可是
至少你没有遗憾
正文:
上次的夜光练习:
- 使用程序判断一个整数是偶数还是奇数
- 使用程序判断假设今天是星期4,那么问10天后的今天是星期几?
- 将数值表达式使用java程序翻译,并通过程序求出运算结果
其中int x=1;int y=2,int a=3,int b=4,int c=5;
案例一:
public static void main(String[] args) { // 判断一个整数一奇数还是偶数 int x = -100; // 奇数是,1,3,5...偶数是2,4,6...显然整数除2能整除,也就%(取模)结果为0就是偶数。 int result = x % 2; System.out.println(result); // 使用判断语句进行判断。 if (result == 0) { System.out.println(x + "是偶数"); } else { System.out.println(x + "是奇数"); } } |
方案二 使用判断该数结果是否是奇数。
(但是该算法有问题,如果被判断的整数为负数是否有效?)
public static void main(String[] args) { // 判断一个整数一奇数还是偶数 int x = 1; // 奇数是,1,3,5...偶数是2,4,6...显然奇数%的结果为1. int result = x % 2; System.out.println(result); // 使用判断语句进行判断。 if (result == 1) { System.out.println(x + "是奇数"); } else { System.out.println(x + "是偶数"); } } |
改进
public static void main(String[] args) { // 判断一个整数一奇数还是偶数 int x = -1; // 奇数是,1,3,5...偶数是2,4,6...显然奇数%的结果为1. int result = x % 2; System.out.println(result); // 使用判断语句进行判断。 if (result != 0) { System.out.println(x + "是奇数"); } else { System.out.println(x + "是偶数"); } } |
案例三:判断星期
public static void main(String[] args) { // 设定今天是星期1,用int 1表示星期一,0表示星期天 int today = 1; // 十天后是星期几?,一个星期是7天,7天之后又是星期1,可以用? int future = (today+10) % 7; if (future == 0) { System.out.println("10天后是星期天"); } else { System.out.println("10天后是星期:" + future); }
} |
案例4:
int x = 1; int y = 2; int a = 3; int b = 4; int c = 5; int result = (3 + 4 * x) / 5 - 10 * (y - 5) * (a + b + c) / x + 9* (4 / x + (9 + x) / y); System.out.println(result); // 442 |
赋值运算符
= , +=, -=, *=, /=, %=
运算符 |
运算 |
范例 |
结果 |
= |
赋值 |
a=3,b=2 |
a=3,b=2 |
+= |
加等于 |
a=3,b=3;a+=b; |
a=5,b=2; |
-= |
减等于 |
a=3,b=2,a-=b; |
a=1,b=2; |
*= |
乘等于 |
a=3,b=2,a*=b; |
a=6,b=2 |
/= |
除等于 |
a=3,b=2,a/=b; |
a=1,b=2; |
%= |
模等于 |
a=3,b=2,a%=b; |
a=1,b=2 |
a+=b 可以想象成 a=a+b;
变量声明完了之后,可以使用赋值语句(assignment statement)给变量赋一个值,Java中使用等号(=)作为基本的赋值运算符(assignment operator),
格式如下:
variable = expression; 变量 = 表达式;
|
变量我们已经知道如何声明,表达式具体如何定义?
表达式的定义:
表达式涉及到值(常量),变量和通过运算符计算出的值,以及他们组合在一起计算出的新值。
x =y+1;
例如:
public static void main(String[] args) { int x = 1; // 声明int变量x, 赋值1给变量x int y = 0; // 声明int变量y, 赋值0给变量y double area; // 声明double变量area double radius = 1.0; // 声明double变量radius,并赋值1.0给变量radius x = 5 * (3 / 2) + 3 * 2; // 将=右半部分表达式的计算结果赋值给变量x x = y + 1; // 将变量y和1的求和的值赋值给变量x area = radius * radius * 3.14159; // 将计算面积的值赋值给变量area } |
赋值运算符小问题
问题1: int x; Syst2intln(x = 1); 如何理解? 答:等价于 x=1; System.out.println(x); 注意:不能 1=x,变量名必须在赋值运算符的左边。
|
问题二: int x; int y; int z; x = y = z = 100; 如何理解? 答:等价于 int x; int y; int z; z = 100; y = z; x = y;
|
问题三:short s1 = 1; s1= s1+1; s1+=1; 问:s1= s1+1; s1+=1; 与有什么不同? 对于short s1 = 1; s1 = s1 + 1; 由于s1+1运算时会自动提升表达式的类型,所以结果是int型,再赋值给short类型s1时,编译器将报告需要强制转换类型的错误。 对于short s1 = 1; s1 += 1;由于 += 是java语言规定的运算符,java编译器会对它进行特殊处理,因此可以正确编译。
|
比较运算符
如何比较两个值?使用比较运算符 3和5谁大,在java中如何比较?
比较运算符比较的两边操作数,结果都是boolean的,只有true和false两种结果。
运算符 |
运算 |
例子 |
结果 |
== |
相等于 |
4= =3 |
false |
!= |
不等于 |
4!= 3 |
true |
< |
小于 |
4 < 3 |
flase |
> |
大于 |
4>3 |
true |
<= |
小于等于 |
4<=3 |
false |
>= |
大于等于 |
4>=3 |
true |
Instanceof |
检查是否是类的对象 |
"hello"instanceof String |
true |
注意的细节:
1.使用比较运算符的时候,要求两种数据类型必须一致。
byte、short、char 会自动提升至int。
逻辑运算符
什么是逻辑运算符?连接比较运算符的符号称之为逻辑运算符。那么为什么要连接比较运算符? 举例:当你去公司应聘,招聘要求,男性(判断为真),并且开发经验1年(判断为假)那么,我们还适合去面试吗,不能,因为只满足了一项,总体是不满足的(总体结果为假)。
逻辑运算符用于对boolean型结果的表达式进行运算,运算的结果都是boolean型。我们的比较运算符只能进行一次判断,对于对此判断无能为力,那么逻辑运算符就可以经将较运算符连接起来。
逻辑运算符用于连接布尔型表达式,在Java中不可以写成3<x<6,应该写成x>3 & x<6 。
“&”和“&&”的区别:单与时,左边无论真假,右边都进行运算;双与时,如果左边为真,右边参与运算,如果左边为假,那么右边不参与运算。
“|”和“||”的区别同理,双或时,左边为真右边不参与运算。
“ ^ ”异或与“|”或的不同之处是:当左右都为true时,结果为false。
& 与 | 或 ^ 异或 ! 非
1、& 与
true & true = true ; false & true= false; true & false = false; false & false= false;
|
总结 & 符号特点
& : 只要两边的boolean 表达式结果,有一个false.那么结果就是false
只有两边都为true ,将结果为true.
2、| 或
true | true =true; ture | false =true; false | true =true; false | false =flase; |
总结 | : 两边只要有一个为真结果就为真,当两边同为假时结果才为假.
3、^ 异或
true ^ true =false; ture ^ false =true; false ^ true= true; false ^ false=flase; |
^ : 两边相同结果是false
两边不同结果是true;
4、! 非
!true = false !false= true
|
5、&& 短路
研究发现,&运算只有两边全为真的时候,结果才为真,那么当左边为假的时候就没有必要在进行判断,&&就产生了。
int a =4;
a >3 && a< 6;
a >3 & a< 6 ;
在这种情况下世没有区别的
如果:
a =2
a >3 & a< 6 2大于 3 为假, 接着运算 2 小于6 为真,总的结果为假
a >3 && a< 6; 此时a 不大于3 结果为false 右边不运算了.即短路.所以&& 比& 效率稍微高了一点.
public static void main(String[] args) { int x = 0; int y = 1; if (x == 0 && y == 1) { System.out.println(x + y); } } |
位运算符
按位操作符用来操作整数基本数据类型中的单个比特(bit),就是二进制,按位操作符会对两个参数中对应的位(bit)执行布尔运算,最终生成一个结果。按位操作符来源于C语言面向底层的操作,Java设计的初衷是嵌入式电视机机顶盒,所以面向底层的操作也保留了下来。
任何信息在计算机中都是以二进制的形式保存的,”&”、“|”、“^”除了可以作为逻辑运算符也可以作为位运算符。位运算是直接对二进制进行运算。他们对两个操作数中的每一个二进制位都进行运算。例如int是由32个二进制数组成,因此使用位运算符可以对整数值的二进制数进行运算。
位(bit)运算符:
位运算符
|
运算符含义
|
& |
与(AND) |
| |
或(OR) |
^ |
异或 |
~ |
取反 |
规则:
可以把1当做true 0当做false
只有参与运算的两位都为1,&运算的结果才为1,否则就为0。
只有参加运算的两位都是0,| 运算的结果才是0,否则都是1。
只有参加运算的两位不同,^ 运算的结果才为1,否则就为0。
1、& 与运算
& 参见运算的两位数都为1,&运算符结果才为1,否则就为0。
6&3
00000000 |
00000000 |
00000000 |
00000110 |
6 |
00000000 |
00000000 |
00000000 |
00000011 |
3 |
00000000 |
00000000 |
00000000 |
00000010 |
& =2 |
2、| 或运算
| 参与运算的两位都为0,|运算的结果才为0,否则就为1。
00000000 |
00000000 |
00000000 |
00000110 |
6 |
00000000 |
00000000 |
00000000 |
00000011 |
3 |
00000000 |
00000000 |
00000000 |
00000111 |
| =7 |
|
|
|
|
|
3、^ 异或运算
^只有参加运算的两位不同,^运算的结果才为1,否则就为0。
00000000 |
00000000 |
00000000 |
00000110 |
6 |
00000000 |
00000000 |
00000000 |
00000011 |
3 |
00000000 |
00000000 |
00000000 |
00000101 |
^ =5 |
- ~ 反码
就是取反,二进制只有1和0,取反就是如果为1,取反就是0,如果是0,取反就是1。
0000-0000 |
0000-0000 |
0000-0000 |
0000-0110 |
6 |
1111-1111 |
1111-1111 |
1111-1111 |
1111-1001 |
取反 -7 |
System.out.println(~6);//-7
结论:当参与取反的数值是正数时,把对应的值加上负号,再-1;
当参与取反的数值是负数时,把对应的值加上负号,再-1;
负数的表现形式就是对应的正数取反,再加1。负数的最高位肯定是1。
4、负数表示
负数对应的正数的二进制-1,然后取反。
-6
0000-0000 |
0000-0000 |
0000-0000 |
0000-0110 |
6 |
1111-1111 |
1111-1111 |
1111-1111 |
1111-1001 |
取反 |
1111-1111 |
1111-1111 |
1111-1111 |
1111-1010 |
加1 |
5、异或特点
一个数异或同一个数两次,结果还是那个数. 用处一个简单的加密思想.
6^3^3
0000-0000 |
0000-0000 |
0000-0000 |
0000-0110 |
6 |
0000-0000 |
0000-0000 |
0000-0000 |
0000-0011 |
^3 |
0000-0000 |
0000-0000 |
0000-0000 |
0000-0101 |
|
0000-0000 |
0000-0000 |
0000-0000 |
0000-0011 |
^3 |
0000-0000 |
0000-0000 |
0000-0000 |
0000-0110 |
结果是6 |
除了这些位运算操作,还可以对数据按二进制位进行移位操作,Java的移位运算符有三种。
练习:取出一个二进制的某一段。
使用异或(^)数据对数据加密
对两个变量的值进行互换。
方式1:
对两个变量进行值交换(不能使用第三个变量)
方式2:
两个数相加的时候,值有可能超出int表示范围,不推荐。
方式3:
该方式虽然效率高,而且避免了超出int值,但是可读性较差。
三种方式都可以对两个变量的值进行交换,但是推荐使用第一种。(面试除外)
移位操作符
<< 左移
>> 右移
>>> 无符号右移
位运算符 |
||
运算符 |
运算 |
范例 |
<< |
左移 |
3 << 2 = 12 --> 3*2*2=12 |
>> |
右移 |
3 >> 1 = 1 --> 3/2=1 |
>>> |
无符号右移 |
3 >>> 1 = 1 --> 3/2=1 |
& |
与运算 |
6 & 3 = 2 |
| |
或运算 |
6 | 3 = 7 |
^ |
异或运算 |
6 ^ 3 = 5 |
~ |
反码 |
~6 = -7 |
位运算符的细节 |
|
<< |
空位补0,被移除的高位丢弃,空缺位补0。 |
>> |
被移位的二进制最高位是0,右移后,空缺位补0; 最高位是1,空缺位补1。 |
>>> |
被移位二进制最高位无论是0或者是1,空缺位都用0补。 |
& |
二进制位进行&运算,只有1&1时结果是1,否则是0; |
| |
二进制位进行 | 运算,只有0 | 0时结果是0,否则是1; |
^ |
任何相同二进制位进行 ^ 运算,结果是0;1^1=0 , 0^0=0
不相同二进制位 ^ 运算结果是1。1^0=1 , 0^1=1 |
技巧:可以理解为二进制1就是true,0就是false。
案例:
1、左移 (算术移位)
3<< 2 是如何在计算机里是实现的?
首先将3转换为2进制,
00000000 |
00000000 |
00000000 |
00000011 |
3 的二进制 |
||
00000000 |
00000000 |
00000000 |
000011 |
左移2位,砍掉高位 |
||
0000 0000 |
0000 0000 |
0000 0000 |
0000 1100 |
低位补0 |
结果是12,所以3<<2 =12;
结论:左移就相当于乘以2的位移个数次幂.
2、右移
6>>2
00000000 |
00000000 |
00000000 |
00000110 |
6的二进制 |
||
000000 |
00000000 |
00000000 |
00000001 |
右移10被砍掉 |
||
00000000 |
00000000 |
00000000 |
00000001 |
高位补0 |
结果是1,所以6>>2 =1;
结论一个数往左移越移越大,往右边移越来越小.
推论
3<<2=12; 3<<1=6 ; 3<<3=24;
3*4=12 ; 3*2=6; 3*8=24;
3*22=12; 3*21=6 3*23 =24;
结论往左移几位就是乘以2的几次幂。
右移规律
6>>2=1 ;6>>1=3 ;
6/4=1 ; 6/2=3 ;
右移两位就是除以 2的2次方,右移一位就是除以 2的一次方。
总结 :>> 是除以2的移动位数次幂
<< 是乘以2的移动位数次幂
用处:最快的运算是位运算。
练习:最有效率的方式算出2乘以8等于几?
3、无符号右移 (逻辑移位)
通过演示发现右移时高位就空了出来, >> 右移时高位补什么要按照原有 数据的最高位来决定。
1111-1111 1111-1111 1111-1111 1111-1010 -6>>2
1111-1111 1111-1111 1111-1111 1111-0010
最高位补什么要看原有最高位是什么
那么使用>> 后原来是最高位1 的那么空出来的最高位还是1 的,是0的还是0。
如果使用>>> 无论最高位是0还是1 空余最高位都拿0 补,这就是无符号右移。
1111-1111 1111-1111 1111-1111 1111-1010 -6>>>2
001111-1111 1111-1111 1111-1111 1111-10
结果是;1073741822
三元运算符
格式
(条件表达式)?表达式1:表达式2;
如果条件为true,运算后的结果是表达式1;
如果条件为false,运算后的结果是表达式2;
示例:
1获取两个数中大数。
int x=3,y=4,z;
z = (x>y)?x:y;//z变量存储的就是两个数的大数。
int x = 1; int y = 2; int z; z = x > y ? x : y; System.out.println(z); //2 |
2判断一个数是奇数还是偶数。
int x=5; System.out.println((x%2==0?"偶数":"奇数")); |
- 运算符的优先级与结合性
夜光:作业
- 按照标准步骤完成hello world打印。
- 如果定义一个变量,如何使用变量。
- 基本数据类型有哪些?
- 'a'+1,结果是什么?为什么?都做了什么事情呢?
- ++在前,在后的区别?
- short s = 3; s = s+2; s+=2,有什么区别,为什么?
- &和&&的区别?