java基础知识之深入理解运算符
2.9java运算符
2.9.1什么是运算符?
- 定义:运算符是一种特殊符号,用以表示数据的运算,赋值和比较且不同的运算符用来完成不同的运算
2.9.2为什么要用运算符?
- 运算符和表达式是java程序的基本组成元素,java语言使用运算符将一个或者多个操作数连缀在一起成执行语句,形成表达式。
- 表示式是由运算符和操作数按一定语法规则组成的符号序列,表达式经过四则运算后都会产生一个确定的值
例如:int num=5+4;
分析例子:
- =和+是运算符
- 运算符左右变量的内容称之为操作数:5、4、num
- 5+4称之为表达式,最后可以有一个确定的值
- int num=5+4;是一条执行语句,以;结束一条语句
2.9.3运算符的分类
- 运算符按照操作数数目来分:单目运算符、双目运算符、三目运算符
- 运算符按功能分:
- 赋值运算符:=
- 算术运算符:+ - * / % ++ –
- 扩展运算符:+= -= *= /= %= >>= <<= ^= ~=
- 关系运算符:> < >= <= == != instanceof
- 逻辑运算符:& | ! ^ && ||
- 位运算符:& | ^ >> << <<< ~
- 条件运算符:?:
i.赋值运算符
=
将赋值运算符右侧的结果赋值给左侧的变量进行存储- 自右向左进行运算
int num=10;
ii.算术运算符
+号的用法
- 实例1:
public class Operator01{
public static void main(String[] args){
//作为正数
int num=+5;
System.out.println(num);
//作为加号
num=5+3;
System.out.println(num);
//作为连接符号
System.out.println("1+1="+1+1);
System.out.println("1+1="+(1+1));
}
}
注意事项:
- 作为正号时,在数值之前编写。
- 作为加法运算,保证+左右两边操作数是一个具体的数值
- 作为连接符号,+左右两边有一个操作数是字符串类型时(String),此时+是连接符号,它的运算规则会将左右两边的操作数都当成是字符串,然后进行拼接(拼接的结果还是字符串)。当出现加号为字符串拼接时,要想先进行四则运算,最好通过用()保证先计算运算结果,后进行字符串拼接。
-号用法
public class Operator02{
public static void main(String[] args){
//作为负号
int num=-5;
System.out.println(num);
//作为减号
num=5-4;
System.out.println(num);
}
}
注意事项:
- 作为负号时,在数值之前编写
- 作为减法运算,保证+左右两边操作数是一个具体的数值
*和/及%法用法
- 实例2:
public class Operator03{
public static void main(String[] args){
//作为乘法
int num=5*3;
System.out.println(num);
//作为除法
num1=num/15;
System.out.println(num1);
//作为取余
num2=num%10;
System.out.println(num2);
}
}
++和--用法
- 实例3:
public class Operator04{
public static void main(String[] args){
int num1=10;
int num2=10;
//使用++自增运算符,++是一条单独语句
++num1;
num2++;
System.out.println("num1的值为:"+num1);
System.out.println("num2的值为:"+num2);
int num3=10;
int num4=10;
//使用———自减运算符,--是一条单独语句
--num3;
num4--;
System.out.println("num3的值为:"+num3);
System.out.println("num4的值为:"+num4);
}
}
/*运算结果:
num1的值为:11
num2的值为:11
num3的值为:9
num4的值为:9
*/
//++和--不是单独一条语句时
public class Operator05{
public static void main(String[] args){
int num1=10;
int num2=10;
int a=num1++;
int b=++num2;
System.out.println("a的值为:"+a+"num1的值为:"+num1);
System.out.println("b的值为:"+b+"num2的值为:"+num2);
int num3=10;
int num4=10;
int c=num3--;
int d=--num4;
System.out.println("c的值为:"+c+"num3的值为:"+num3);
System.out.println("d的值为:"+d+"num4的值为:"+num4);
}
}
/*运算结果:
a的值为:10 num1的值为:11
b的值为:11 num2的值为:11
c的值为:10 num3的值为:9
d的值为:9 num4的值为:9
*/
- ++和–在变量前后的联系:
- ++运算符是在原来变量的基础上自增1,–运算符是在原来的变量的基础上自减1
- 当++和–是一条单独的语句时,++或–在变量的前后没有区别,都是自增或自减1
- ++和–在变量前后的区别:
- ++num不是单独一条语句是,前加,先自增 再运算。
- num++不是单独一条语句时,后加,先运算 再自增
- –num不是单独一条语句是,前减,先自减 再运算。
- num–不是单独一条语句时,后加,先运算 再自减
iii.扩展运算符
- 本质就是算术运算符和位运算符+赋值运算符的一个结合体。
public class Operator06{
public static void main(String[] args){
//计算两个学生的分数之和
int zhangScore=44;
int liScore=33;
int sum=0;
sum+=zhangScore;//等同于sum=sum+zhangScore;
sum+=liScore;//等同于sum=sum+liScore;
System.out.println("sum的值为:"+sum);
}
}
//计算结果是:sum的值为:77
public class Operator07{
public static void main(String[] args){
int a=44;
byte b=33;
byte b+=a;//相当于byte b=(byte)(a+b);
System.out.println("b的值为:"+sum);
}
}
//计算结果是:b的值为:77
扩展运算符的有优缺点:
- 优点
- 提高了编译速度
- 提高了编写速度
- 自动强制类型转换(隐藏着可以会出现的精度问题,不推荐使用)
- 缺点
- 不利于阅读
什么时候用扩展符?
- 赋值符号的左右变量有一个同名操作数,建议逐渐往扩展运算符进行编写。
规则:数据类型 变量名1=变量名1+变量名2=>数据类型 变量名1+=变量名2
iv.关系运算符
public class Operator08{
public static void main(String[] args){
boolean flag1=4>10;
System.out.println(flag1);
boolean flag2=4!=5;
System.out.println(flag2);
boolean flag3=1*31+22>33;
System.out.println(flag3);
boolean flag4="hello"=="hello";
System.out.println(flag4);
System.out.println("hello">"hello");
//出现二元运算符'>'的操作数类型错误,字符串不可以进行比较
int flag5=1+true;
System.out.println(flag5);
//出现二元运算符'+'的操作数类型错误,boolean类型的值不能参与四则运算
}
}
/*计算结果:
flag1=false
flag2=ture
flag3=true
flag4=ture
*/
- 注意事项:
- 通过比较运算符结果是一个boolean类型的值true或false
- !=和==既可以比较基本数据类型,也可以比较引用类型
- < > >= <=只能比较基本数据类型(布尔类型除外)
v.逻辑运算符
- 逻辑运算符中囊括了(& | ! ^ && ||),逻辑运算符左右变量的操作数只能是boolean类型的值。
- 注意:当&、|、左右两边的操作数不是boolean类型,是数值型时要注意,此时&、|、不是逻辑运算符而是位运算符。
public class Operator09{
public static void main(String[] args){
//测试逻辑&运算符
System.out.println(true&true);
System.out.println(true&false);
System.out.println(false&true);
System.out.println(false&false);
//测试逻辑&&运算符
System.out.println(true&&true);
System.out.println(true&&false);
System.out.println(false&&true);
System.out.println(false&&false);
//测试逻辑|运算符
System.out.println(true|true);
System.out.println(true|false);
System.out.println(false|true);
System.out.println(false|false);
//测试逻辑||运算符
System.out.println(true||true);
System.out.println(true||false);
System.out.println(false||true);
System.out.println(false||false);
// 测试逻辑!运算符
System.out.println(!true);
System.out.println(!false);
//测试逻辑^运算符
System.out.println(true^true);
System.out.println(true^false);
System.out.println(false^true);
System.out.println(false^false);
}
}
- 逻辑运算符最后的结果:
- &和&&左右两边的操作数都为true,其结果才为true。
- |和||左右两边的操作数有一个为true,其结果就为true。
- ^左右两边的操作数相同为false,不同为true。
- !取反,true->false false->true
- &&和&的区别以及联系,||和|的区别和联系
- 联系
- &和&&左右两边的操作数都为true,其结果才为true
- |和||左右两边的操作数有一个为true,其结果就为true
- 区别
- &&当左边第一个操作数为false的情况下不会对第二个操作数进行运算,因为结果一定为false
- ||当左边第一个操作数为true的情况下不会对第二个操作数进行运算,因为结果一定为true
- 联系
vi.位运算符
- ^、&、|、~、>>、<<、>>>,位运算符就是基于二进制直接进行运算
- 计算机中二进制运算都是补码运算,原码用于展示
- 运算符符号位也会参与运算,尤其是在>>、<<、>>>位运算符中,一定要记住
- false->0;true->1
1.按位异或^
运算规则表:
按位^ | 1 | 0 |
---|---|---|
1 | 0 | 1 |
0 | 1 | 0 |
- 两个相同的数字进行^运算,其结果就是0
- 0和任何数进行^运算,结果就是对应数。
- 两个变量互相^三次,就可以互相交换位置。
public class Operator10{
public static void main(String[] args){
int num1=10;
int num2=20;
/*第一种交换方式借助第三方变量
int temp=0;
temp=num1;
num1=num2;
num2=temp;
System.out.println("num1为:"+num1+"num2为:"+num2);*/
//第一种交换方式通过异或^
num1=num1^num2;
num2=num1^num2;//num2=num1^num2^num2
num1=num1^num2;//num1=num1^num2^num1
}
}
2.按位&
运算规则表:
按位& | 1 | 0 |
---|---|---|
1 | 1 | 0 |
0 | 0 | 0 |
- 一个数字如何按位&为1,其结果也为1,那就是该数字最后一位(二进制数最后一位)为1
public class Demo01{
public static void main(String[] args){
System.out.println(5&-3);//结果是5
System.out.println(5&3);//结果是1
}
}
3.按位|
运算规则表:
按位| | 1 | 0 |
---|---|---|
1 | 1 | 1 |
0 | 1 | 0 |
public class Demo02{
public static void main(String[] args){
System.out.println(5|3);//结果是7
}
}
4.按位~
运算规则表:
按位~ | 1 | 0 |
---|---|---|
0 | 1 |
public class Demo03{
public static void main(String[] args){
System.out.println(~5);//结果是:-6
}
}
5.按位左移<<
public class Demo04{
public static void main(String[] args){
System.out.println(2<<3);//结果是:16
System.out.pritnln(-2<<3);//结果是:-16
}
}
- 一个数字number按位左移N位,相当于当前number*2^N
- 当一个数左移N位,而且N超过了数字类型的取值范围,相当于number<<(N%32)
- 左移之后,不论符号位是正负,末尾缺少的位数通过0来填充
6.按位右移>>
public class Demo05{
public static void main(String[] args){
System.out.println(8>>2);//结果是:2
System.out.pritnln(-8>>2);//结果是:-2
}
}
- 当一个数字(a)右移N位之后,就是除以当前数字的除以2的N次方 (a>>N => a/2^N)
- 右移之后如果当前数是正数,那么填补空位通过 0 ,反之通过 1 填补,就是填补空位通过当前数字的 符号位来决定。
7.无符号位右移>>>
public class Demo06{
public static void main(String[] args){
System.out.println(-8>>2);//结果为:-2
System.out.println(-8>>>2);//结果为:1073741822
System.out.println(8>>2);//结果为:2
System.out.println(8>>>2);//结果为:2
}
}
- 当一个正数进行无符号右移操作时和右移操作的结果是一样的。
- 当一个负数进行无符号右移操作时得出的结果一定是一个正数。
- 无符号右移填补空位全部都是通过0填补。
vii.条件运算符
- 语法格式:
表达式1?表达式2:表达式3
- 表达式1的结果一定是一个boolean类型的值
- 条件运算符是三目运算符,可以连接三个操作数
- 当表示式1的值为true时,整个条件运算符的结果是表达式2,反之,表达式1的值为false时,整个条件运算符的结果是表达式3
- 表达式2和表达式3可以是值,也可以是字符串
- 注意:对于条件运算符运算最后的出的结果,不论是表达式2还是表达式3,都要有相应的输出,可以直接用输出语句输出,也可以用对应的变量去存储,否则编译会出错
import java.util.Scanner;
public class Demo07{
public static void main(String[] args){
//声明Scanner类型的变量
Scanner input=new Scanner(System.in);
System.out.println("==请输入用户名===");
int uname=input.nextInt();
//2:声明一个变量方法存储的用户名
int regUname=123;
//3:输出如果用户名相同则输出恭喜登录成功反之用户名或者密码错误
//方法一:用变量输出
String msg=uname==regUname?"恭喜登录成":"用户名或者密码错误";
System.out.println(msg);
//方法二:用输出语句输出
System.out.println(uname==regUname?"恭喜登录成":"用户名或者密码错误");
}
}
程序执行顺序:
- 首先计算表达式1的值,如果表达式1的值是true,整个条件运算符的结果是表达式2的值;
- 如果表达式1的值是false,那么整个条件运算符的结果是表达式3的值。
- 注意:条件运算符最后会计算出来一个结果,对于该结果而言,要么直接输出,要么通过变量存储,否则编译会出错。
- 条件运算符在一定程度上帮助我们解决流程控制的问题,可以代替一部分后续学习的if语句。
2.9.4运算符优先级
i.运算符优先级判断方法
-
单目>双目>三目
-
算术>关系>逻辑>条件运算符>扩展运算符、赋值符号(优先级最低)
-
书写时,为了逻辑清楚:用括号,括号是无敌的
ii.运算符优先级表
public class Demo08{
public static void main(String[] args){
int i=4;
int j=5;
System.out.println(i++-j+i-->>i%2+(i++>j?j--:j));
System.out.println(i+"=="+j)
}
}
运算结果:
第一步:i++-j+i-->>i%2+5 i的值从4变为5,j的值没有变
第二步:5-j+i-->>i%2+5 i的值从4变为6,j的值没有变
第三步:5-j+6>>i%2+5 i的值从6变为5,j的值没有变
第四步:5-j+6>>1+5
第五步:5-j+6>>1+5=>6>>1+5=>6>>6=>0
补充一下上一篇文章中的漏的知识点内容:
2.8.5常量的命名规则
- 遵守标识符的命名规则
- 常量的书写格式是:变量名所有字母都要大写,单词之间通过_下划线隔开。例如:NAN_CHANG_MA_GE