Unit6 运算符与表达式
程序是由许多语句组成,而语句组成的基本单位就是表达式与运算符。Java中的运算符主要分为4类:算术运算符、关系运算符、逻辑运算符和位运算符。
运算符:进行运算符的符号。
表达式:运算符+操作数。
1 运算符
1.1 赋值运算符
为不同类型的变量赋值,就需要用到赋值运算符“=”,将等号右边的值赋给等号左边的变量,注意:赋值的数据类型要左右一致或左侧接收值变量的类型等级要比值类型的等级高。
//赋值运算符
int num = 100 ;//将100赋值给int类型的num变量
byte num2 = 100 ; //将100赋值给byte类型的num2变量
num= num2;//虽然不是一类型,但是num变量表示范围比num2范围大,所以可以接收num2的值
1.2 一元运算符
使用一个运算符完成对操作数本身的运算,称为一元运算符。
l +:正号
num3 = +num3;//+正号,值为4
l -:负号
num3 = -num3;//-:负号值为-4
l !:NOT 非
boolean boo = !true; //!:取反 NOT 非 值为false 只能操作boolean类型
num3 = !num3;//使用在int类型上报错
l ~:对补码按位取反
byte num4 = 4;
num4 = (byte)~num4;//4的原码为:0000 0100 补码与原码一样然后按位取反:1111 1011 值为-5 为什么对补码取反?
在计算机中,存储的数据是二进制格式,负数是以补码的形式存储。所以任何负数的位运算,都是对补码的运算。
l ++:自增,对自身的值+1
/*
* 在对数值进行操作时(包括赋值运算、打印操作、传参操作),自增符号++在前时,
*先对数值本身进行+1操作,再执行其他操作,++在后时,先执行其他操作,再对数值本身进行+1操作
*/
byte num5 = 10;
num5 = num5++;
System.out.println(num5);//打印结果为10
byte num6 = 10;
num6 = ++num6;
System.out.println(num6);//打印结果为11
l --:自减
/*
* 在对数值进行操作时(包括赋值运算、打印操作、传参操作),自减符号--在前时,
*先对数值本身进行-1操作,再执行其他操作,--在后时,先执行其他操作,再对数值本身进行-1操作
*/
byte num7 = 10;
num7 = num7--;
System.out.println(num7);//打印结果为10
byte num8 = 10;
num8 = --num8;
System.out.println(num8);//打印结果为9
l 注意事项:
byte num9 = 10;
num9 = num9 +1;//报错,因为num9是byte类型,1是整数类型,需要强制转换一下
num9= num9++;//不报错,是因为是在其本身进行一个自我的递增操作,java底层代码内部实现
1.3 算术运算符
数值与数值之间的基本运算:+、-、*、/、%。
//算术运算符
int num10 = 10;
num10 = num10+ 10;//这里的"+"表示加法运算。
System.out.println("结果为:"+num10);//打印结果20,+字符串与数字连接表示连接符,连接的数字被转为字符串。
int num11 = 10;
num11 = num11- 10;//这里的"-"表示减法运算。
System.out.println("结果为:"+num11);//打印结果0
int num12 = 10;
num12 = num12* 10;//这里的"*"表示乘法运算。
System.out.println("结果为:"+num12);//打印结果100
int num13 = 13;
num13 = num13/ 10;//这里的"/"表示除法运算,如果是整数类型运算,就是整除。需要保留小数位,则将参与运算的操作数转为浮点型,并且以浮点型变量来接收。
num3 = numf / num2;
System.out.println("结果为:"+num13);//打印结果3
int num14 = 14;
num14 = num14% 10;//这里的"%"表示取余数运算。通过判断运算结果,可以知道一个是是否可以被另一个数整除
System.out.println("结果为:"+num14);//打印结果4
//注意,当进行除法时,需要保留小数位,运算式中,必须有浮点型数据参与运算。
float num15 = (float)num15/4;//int类型14除以浮点型4,自动将结果转为浮点型,或者使用强制转换
System.out.println(num15);//打印结果:3.75
float num16 = 4 * 4;//当进行乘法运算时,int类型的结果可以自动转为float类型
System.out.println(num16);//打印结果16.0
float num17 = 15.15f;//如果不包含小数位以后的数字,那么写不写f都可以,为什么??
System.out.println(num17 % 10);//结果为5.1499996,浮点型也可以进行取余数运算
1.4 逻辑运算符
逻辑运算符只对boolean数据类型操作数进行运算,参与运算的数据与返回的数据类型都是boolean类型。(true或false)
&、&&:“与”运算符两边值都是true,结果则为true。(真真为真)
|、||:“或”运算符两边有一个值为true,结果则为true。(有真则真)
!:“非”运算符,对数据值进行取反。
//&、&&真真为真
System.out.println(true&true);//true
System.out.println(true&false);//false
System.out.println(false&false);//false
System.out.println(true&&true);//true
System.out.println(true&&false);//false
System.out.println(false&&false);//false
//|、||有真则真
System.out.println(true|true);//true
System.out.println(true|false);//true
System.out.println(false|false);//false
System.out.println(true||true);//true
System.out.println(true||false);//true
System.out.println(false||false);//false
//取反
System.out.println(!true);//false
&&、||和&、|的区别:当使用这两个运算符运算时,当运算符左边的结果已经起到决定性作用时,就不会再去判断运算符右侧的数值。
//&&、||的区别:
int num18 = 10;
int num19 = 20;
boolean boo1 = ++num18==18&--num19==19;//当num18==18结果已经为flase时候,还会去执行右边的操作
System.out.println("结果"+boo1+"---num18的值为:"+num18+"----num19的值为:"+num19);
int num20 = 10;
int num21 = 20;
boolean boo2 =++num20==20&&--num21==19;//当num==20结果已经为flase时候,就不再去执行右边的操作
System.out.println("结果"+boo2+"---num20的值为:"+num20+"----num21的值为:"+num21);
int num22 = 10;
int num23 = 20;
boolean boo3 =++num22==11|--num23==19;//当num22==11结果已经为true时候,还会去执行右边的操作
System.out.println("结果"+boo3+"---num22的值为:"+num22+"----num23的值为:"+num23);
int num24 = 10;
int num25 = 20;
boolean boo4 =++num24==11||--num25==19;//当num24==11结果已经为ture时候,就不再去执行右边的操作
System.out.println("结果"+boo4+"---num24的值为:"+num24+"----num25的值为:"+num25);
1.5 位运算符
对操作数的二进制数据的补码按位进行运算操作。
l >>:右移;
//位运算
//>>:右移
int num26 = 16;
System.out.println(num26>>1);//结果:8
System.out.println(num26>>2);//结果:4
System.out.println(num26>>3);//结果:2
System.out.println(num26>>4);//结果:1
System.out.println(num26>>5);//结果:0
/*
*规律:向右每移动一位相当于在上一次一动基础上除以2,右移n次为:num26/2^n,空出来的部分正数补0,负数补1
*代码分析:
*16:0000 0000 0000 0000 0000 0000 0001 0000 向右移动2位:0000 0000 0000 0000 0000 0000 0000 0010 结果为4
*思考:负数右移结果?
*-16>>2=? 1000 0000 0000 0000 0000 00000001 0000 向右一动2位:0010 00000000 0000 0000 0000 0000 0010 结果为:536,870,914
*应该按照存储的数据来运算,即补码运算:1111 1111 1111 1111 1111 1111 1111 0000 向右移动2位:1111 1111 1111 1111 1111 1111 1111 1100
*/
System.out.println(-16>>2);//结果为:-4 1111 1111 1111 1111 1111 1111 1111 1100
l <<左移;
//<<:左移
int num27 = 3;
System.out.println(num27<< 1);//结果:6
System.out.println(num27<< 2);//结果:12
System.out.println(num27<< 3);//结果:24
System.out.println(num27<< 4);//结果:48
System.out.println(num27<< 5);//结果:96
//规律:向左移动一位,相当于在原有的基础上乘以2,高位抛弃,低位补0,左移n次为:num27*2^n
System.out.println(-3<< 2);//结果为:-12 11111111111111111111111111110100
l >>>:无符号右移;
//无符号右移,高位补零,低位舍去
//也就是说,正数无符号右移和正数的右移是一样的
//越大的负数的无符号右移是一个越大的正数
int num28 = -16;
System.out.println(-4>>> 2);//变为正数
System.out.println(8>>> 2);//与右移一致
l &:与 AND;
//&:与运算,两个二进制数按位运算,都为1,则该位结果为1,否则为0(一一得一)
System.out.println(5 &6);//0000 0101 & 0000 0110 = 0000 0100 结果为:4
l |:或 OR;
//|:或运算,两个二进制数按位运算,有1,则为1,都为0,才是0 (有一得一)
System.out.println(5 | 6);//0000 0101 | 0000 0110 = 0000 0111结果为:7
l ^:异或 XOR;
//^:异或运算,两个二进制数按位运算,不一样,则为1,一样则为0(一零得一)
System.out.println(5 ^ 6);//0000 0101 ^ 0000 0110 = 0000 0011结果为:3
//一个数,异或一个数字两次,还是原来的数字。
l ~:按位取反 NOT。
//~:取反运算,按位取反
System.out.println(~4);//0000 0000 0000 0000 0000 0000 0000 0100 取反:1111 1111 1111 1111 1111 1111 1111 1011 值为 -5
System.out.println(~-4);//:1111 11111111 1111 1111 1111 1111 1100 取反:0000 0000 0000 0000 0000 0000 0000 0011 值为3
1.6 三元运算符
又称三目运算符:结果 = 表达式 ?结果1:结果2
结果可以是任意类型,表达式成立返回结果1,不成立返回结果2。
//三目运算符
int num29 = 5;
int num30 = 5;
int num31 = num29 >num30 ?num29 :num30;//num29大于num30表达式成立,返回num29,不成立返回num30
System.out.println(num31);//结果为5
String str1 =num29 > num30 ?"num29比num30大":"num29没有num30大";//条件成立返回值1,不成立返回值2
//三目运算符的嵌套
str1 = num29> num30 ?"num29比num30大":num29 == num30 ?"num29与num30相等":"num30比num29大";
System.out.println(str1);
1.7 关系运算符与if语句
使用关系运算符对数据进行判断运算,返回布尔类型值。
//关系运算符
System.out.println(1 > 2);//false
System.out.println(1 < 2);//true
System.out.println(1 != 2);//true
System.out.println(1 >=2);//false
System.out.println(1 <=1);//true
System.out.println("aaa"=="aaa");//true,字符串可以使用==进行内容判断
If语句
使用if语句进行条件判断,判断的结果为boolean类型值。
if(条件){代码}
当运算结果为true时,执行if后面代码块的代码
if (num29 > num30){
System.out.println("if语句成立,num29比num30大");
}
1.8 递增与递减运算符
++:自增;--:自减。
1.9 括号运算符
使用()来对运算顺序进行控制。
//括号运算符
System.out.println((1+2)*3);//结果为9
System.out.println(1+2*3);//结果为7
1.10 运算符的优先级
实际中没有必要死死的遵守这个顺序,一般遇到多个运算符直接使用()进行顺序控制即可。
1.11 赋值运算符
//赋值运算符
int num32 = 32;//普通赋值运算符
num32 -= 1;//简写的赋值运算符,结果为31
System.out.println(num32);
2 表达式
2.1 算术表达式
用于数值计算。由算术运算符和操作数组成。
//算术表达式
int num33 = 2 * 8;
2.2 关系表达式
用于程序判断语句中,由关系运算符组成,返回一个布尔类型值。
//关系表达式
if (1 < 2) {
System.out.println("输出代码");
}
2.3 逻辑表达式
使用逻辑运算符进行运算,返回一个布尔类型值。
//逻辑表达式
System.out.println(true & true);
2.4 赋值表达式
由赋值运算符和操作数组成,用于给变量赋值。
//赋值表达式
int num34 = num33;
3 语句
3.1 语句中的空格
代码中,语句中的空格不会影响代码的执行。可以使用空格分隔运算符,便于阅读。
Int num33 = 2 * 8;
3.2 空语句
代码中,什么都不写或者使用;来表示一行代码,也可以运行成功。
if (1 < 2) {
}
3.3 声明语句
基本数据类型变量的声明:数据类型 变量名 = 值;
引用数据类型变量的声明:数据类型 变量名 = new 数据类型();
3.4 赋值语句
使用 = 进行对变量的赋值操作。
4 练习
做一个计算器,可以进行普通运算、以及位运算。
普通计算:加减乘除取余;
位运算:输入位运算的数据,返回位运算的二进制表现形式。
下面是我练习的代码:
package day06;
public class Operator {
public static void main(String[] args) {
//赋值运算符
int num = 100 ;//将100赋值给int类型的num变量
byte num2 = 100 ; //将100赋值给byte类型的num2变量
num = num2;//虽然不是一类型,但是num变量表示范围比num2范围大,所以可以接收num2的值
//一元运算符
int num3 = 4;
num3 = +num3;//+正号,值为4
num3 = -num3;//-:负号 值为-4
boolean boo = !true; //!:取反 NOT 非 值为false 只能操作boolean类型
//num3 = !num3;//使用在int类型上报错
byte num4 = 4;
num4 = (byte)~num4;//4的原码为:0000 0100 补码与原码一样 然后按位取反:1111 1011 值为-5,为什么对补码取反?
/*
* 在对数值进行操作时(包括赋值运算、打印操作、传参操作),自增符号++在前时,
*先对数值本身进行+1操作,再执行其他操作,++在后时,先执行其他操作,再对数值本身进行+1操作
*/
byte num5 = 10;
num5 = num5++;
System.out.println(num5);//打印结果为10
byte num6 = 10;
num6 = ++num6;
System.out.println(num6);//打印结果为11
/*
* 在对数值进行操作时(包括赋值运算、打印操作、传参操作),自减符号--在前时,
*先对数值本身进行-1操作,再执行其他操作,--在后时,先执行其他操作,再对数值本身进行-1操作
*/
byte num7 = 10;
num7 = num7--;
System.out.println(num7);//打印结果为10
byte num8 = 10;
num8 = --num8;
System.out.println(num8);//打印结果为9
byte num9 = 10;
//num9 = num9 +1 //报错,因为num8是byte类型,1是整数类型,需要强制转换一下
num9 = num9++;//不报错,是因为是在其本身进行一个自我的递增操作,java底层代码内部实现
//算术运算符
int num10 = 10;
num10 = num10 + 10;//这里的"+"表示加法运算。
System.out.println("结果为:"+num10);//打印结果20,字符串与数字连接表示连接符,连接的数字被转为字符串。
int num11 = 10;
num11 = num11 - 10;//这里的"-"表示减法运算。
System.out.println("结果为:"+num11);//打印结果0
int num12 = 10;
num12 = num12 * 10;//这里的"*"表示乘法运算。
System.out.println("结果为:"+num12);//打印结果100
int num13 = 13;
num13 = num13 / 10;//这里的"/"表示除法运算。
System.out.println("结果为:"+num13);//打印结果3
int num14 = 14;
num14 = num14 % 10;//这里的"%"表示取余数运算。通过判断运算结果,可以知道一个是是否可以被另一个数整除
System.out.println("结果为:"+num14);//打印结果4
//注意,当进行除法时,需要保留小数位,运算式中,必须有浮点型数据参与运算。
float num15 = 15/4f;//int类型14除以浮点型4,自动将结果转为浮点型,或者使用强制转换
System.out.println(num15);//打印结果:3.75
float num16 = 4 * 4;//当进行乘法运算时,int类型的结果可以自动转为float类型
System.out.println(num16);//打印结果16.0
float num17 = 15.15f;//如果不包含小数位以后的数字,那么写不写f都可以,为什么??
System.out.println(num17 % 10);//结果为5.1499996,浮点型也可以进行取余数运算
//逻辑运算符:
//&、&&真真为真
System.out.println(true&true);//true
System.out.println(true&false);//false
System.out.println(false&false);//false
System.out.println(true&&true);//true
System.out.println(true&&false);//false
System.out.println(false&&false);//false
//|、||有真则真
System.out.println(true|true);//true
System.out.println(true|false);//true
System.out.println(false|false);//false
System.out.println(true||true);//true
System.out.println(true||false);//true
System.out.println(false||false);//false
//取反
System.out.println(!true);//false
//&&、||的区别:
int num18 = 10;
int num19 = 20;
boolean boo1 = ++num18==18&--num19==19;//当num18==18结果已经为flase时候,还会去执行右边的操作
System.out.println("结果"+boo1+"---num18的值为:"+num18+"----num19的值为:"+num19);
int num20 = 10;
int num21 = 20;
boolean boo2 = ++num20==20&&--num21==19;//当num==20结果已经为flase时候,就不再去执行右边的操作
System.out.println("结果"+boo2+"---num20的值为:"+num20+"----num21的值为:"+num21);
int num22 = 10;
int num23 = 20;
boolean boo3 = ++num22==11|--num23==19;//当num22==11结果已经为true时候,还会去执行右边的操作
System.out.println("结果"+boo3+"---num22的值为:"+num22+"----num23的值为:"+num23);
int num24 = 10;
int num25 = 20;
boolean boo4 = ++num24==11||--num25==19;//当num24==11结果已经为ture时候,就不再去执行右边的操作
System.out.println("结果"+boo4+"---num24的值为:"+num24+"----num25的值为:"+num25);
//位运算
//>>:右移
int num26 = 16;
System.out.println(num26>>1);//结果:8
System.out.println(num26>>2);//结果:4
System.out.println(num26>>3);//结果:2
System.out.println(num26>>4);//结果:1
System.out.println(num26>>5);//结果:0
/*
*规律:向右每移动一位相当于在上一次一动基础上除以2,右移n次为:num26/2^n,空出来的部分整数补0,负数补1
*代码分析:
*16:0000 0000 0000 0000 0000 0000 0001 0000 向右移动2位:0000 0000 0000 0000 0000 0000 0000 0010 结果为4
*思考:负数右移结果?
*-16>>2=? 1000 0000 0000 0000 0000 0000 0001 0000 向右一动2位:0010 0000 0000 0000 0000 0000 0000 0010 结果为:536,870,914
*应该按照存储的数据来运算,即补码运算:1111 1111 1111 1111 1111 1111 1111 0000 向右移动2位:1111 1111 1111 1111 1111 1111 1111 1100
*/
System.out.println(-16>>2);//结果为:-4 1111 1111 1111 1111 1111 1111 1111 1100
//<<:左移
int num27 = 3;
System.out.println(num27 << 1);//结果:6
System.out.println(num27 << 2);//结果:12
System.out.println(num27 << 3);//结果:24
System.out.println(num27 << 4);//结果:48
System.out.println(num27 << 5);//结果:96
//规律:向左移动一位,相当于在原有的基础上乘以2,高位抛弃,低位补0,左移n次为:num27*2^n
System.out.println(-3 << 2);//结果为:-12 11111111111111111111111111110100
//无符号右移,高位补零,低位舍去
int num28 = -16;
System.out.println(-4 >>> 2);//变为正数
System.out.println(8 >>> 2);//与右移一致
//&:与运算,两个二进制数按位运算,都为1,则该位结果为1,否则为0(一一得一)
System.out.println(5 & 6);//0000 0101 & 0000 0110 = 0000 0100 结果为:4
//|:或运算,两个二进制数按位运算,有1,则为1,都为0,才是0 (有一得一)
System.out.println(5 | 6);//0000 0101 | 0000 0110 = 0000 0111结果为:7
//^:异或运算,两个二进制数按位运算,不一样,则为1,一样则为0(一零得一)
System.out.println(5 ^ 6);//0000 0101 ^ 0000 0110 = 0000 0011结果为:3
//~:取反运算,按位取反
System.out.println(~4);//0000 0000 0000 0000 0000 0000 0000 0100 取反:1111 1111 1111 1111 1111 1111 1111 1011 值为 -5
System.out.println(~-4);//:1111 1111 1111 1111 1111 1111 1111 1100 取反:0000 0000 0000 0000 0000 0000 0000 0011 值为3
//三目运算符
int num29 = 51;
int num30 = 5;
int num31 = num29 > num30 ?num29 :num30;//num29大于num30表达式成立,返回num29,不成立返回num30
System.out.println(num31);//结果为5
String str1 = num29 > num30 ?"num29比num30大":"num29没有num30大";//条件成立返回值1,不成立返回值2
//三目运算符的嵌套
str1 = num29 > num30 ?"num29比num30大":num29 == num30 ?"num29与num30相等":"num30比num29大";
System.out.println(str1);
//关系运算符
System.out.println(1 > 2);//false
System.out.println(1 < 2);//true
System.out.println(1 != 2);//true
System.out.println(1 >= 2);//false
System.out.println(1 <= 1);//true
System.out.println("aaa"=="aaa");//true,字符串可以使用==进行内容判断
if (num29 > num30) {
System.out.println("if语句成立,num29比num30大");
}
//括号运算符
System.out.println((1+2)*3);//结果为9
System.out.println(1+2*3);//结果为7
//赋值运算符
int num32 = 32;//普通赋值运算符
num32 -= 1;//简写的赋值运算符,结果为31
System.out.println(num32);
//算术表达式
int num33 = 2 * 8;
//关系表达式
if (1 < 2) {
System.out.println("输出代码");
}
//逻辑表达式
System.out.println(true & true);
//赋值表达式
int num34 = num33;
}
}