第4章 运算符
目录
- 运算符介绍
- 算术运算符
- 关系运算符
- 逻辑运算符
- 赋值运算符
- 三元运算符
- 运算符优先级
- 二进制*
- 位运算*
介绍
-
运算符是一种特殊的符号,用以表示数据的运算、赋值和比较等。
-
分类:
1.算术运算符
2.赋值运算符
3.关系运算符(比较运算符)
4.逻辑运算符
5.位运算符(需要二进制基础)
6.三元运算符
算术运算符
前言
介绍
- 算术运算符是对数值类型的变量进行运算的,在Java程序中使用的非常多。
一览表
使用ArithmeticOperator.java
-
+,-,*,/,%,++,–
重点讲解/、%、++
-
自增:++
作为独立的语句使用:
前++和后++都完全等价于i = i + 1;
作为表达式使用:
前++:++i先自增后赋值
后++:i++先赋值后自增 -
–、+、-、*是一个道理,完全可以类推
-
package chapter04.test; public class ArithmeticOperator { public static void main(String[] args) { //除法 System.out.println(10 / 4);//2-->从数学是2.5,但是Java会整数10除以整数4,结果去尾是2 System.out.println(10.0 / 4);//2.5-->Java结果就是2.5了,因为已经统一成小数类型 double d = 10 / 4;//2.0-->Java中10 / 4 = 2-->但是赋值时会提高精度变成2.0 System.out.println(d); //取模(即取余) %本质是 一个公式a % b = a - a / b * b //-10 % 3 --> -10 - (-10) / 3 * 3 = -10 + 9 = -1 //10 % -3 --> 10 - 10 / (-3) * (-3) = 10 - //一正一负运算,符号取"绝对值较大的加数的符号",数值取"用较大的绝对值减去较小的绝对值"的所得值 System.out.println(10 % 3);//1 System.out.println(-10 % 3);//-1 System.out.println(10 % -3);//+1 System.out.println(-10 % -3);//1 //++作为独立语句使用 int i = 10; i++;//自增 等价于i = i + 1; ++i;//自增 等价于i = i + 1; System.out.println("i=" + i);//12 //++作为表达式使用-->就是从左到右依次运算 //前++:++i先自增后赋值 //后++:i++先赋值后自增 int j = 8; //int k = ++j;//等价-->新j=j+1=9;k=新j=9 int k = j++;//等价-->k1=j=8;新j=j+1=9 //System.out.println("k=" + k +"j=" + j);//9;9 System.out.println("k=" + k +"j=" + j);//8;9 } }
练习题
面试题ArithmeticOperatorExercise01.java
-
面试题1
int i = 1;//i=1 i = i++;//规则使用临时变量(1)temp=i-->1;(2)i++-->2;(3)i=temp-->1赋给2-->1 System.out.println(i);//i=1
结果是多少?为什么?
答:1;引入临时变量,本来i=2了,但是临时变量=1重新又赋值给i,i最后还是1。
-
面试题2
int i = 1; i = ++i;//规则使用临时变量(2)temp=i-->2;(1)i=i+1-->先自增2;(3)i=temp-->2赋给2-->2 System.out.println(i);
答:2;先i自增,然后赋值给temp,最后temp又赋回去了
-
输出结果是?
int i1 = 10; int i2 = 20; int i = i1++; System.out.print("i=" + i);//10 System.out.println("i2=" + i2); //20 i = --i2; System.out.print("i=" + i);//19 System.out.println("i2=" + i2);//19
-
假如还有59天放假,问:合xx个星期零xx天放假?
package chapter04.test; public class ArithmeticOperatorExercise02 { public static void main(String[] args) { //1.需求:假如还有59天放假,问:合xx个星期零xx天放假? //2.思路分析:(1)使用int变量 days 保存天数;(2)几周 星期数weeks:days / 7;余多少天 days % 7(3)输出 //3.走代码: int days = 59; int weeks = days / 7; int leftDays = days % 7; System.out.println("合" + weeks +"个星期零" + leftDays + "天放假"); } }
//关注解题思路
-
定义一个变量保存华氏温度,华氏温度转换摄氏温度的公式为:5/9*(华氏温度-100),请求出华氏温度对应的摄氏温度。
double fah = 102; double cet = 5.0 / 9 * (fah - 100); //此处就不能是5/9*(fah-100),前面5/9Java运算会直接保存成整数0,所以后面无论乘以多少结果都是0.0 System.out.println(cet);
//考虑公式和Java语言的特性
关系运算符
介绍
- 关系运算符的结果都是boolean型,也就是要么是true,要么是false
- 关系表达式经常用在if结构的条件中或循环结构的条件中
一览表
使用RelationalOperator.java
-
int a = 9; //提示:开发中不可以使用a,b a1,bc n1,n2... int b = 8; System.out.println(a > b); System.out.println(a >= b); System.out.println(a <= b); System.out.println(a < b); System.out.println(a == b); System.out.println(a != b); boolean flag = a > b;
细节说明
- 关系运算符的结果都是boolean型,也就是要么是true,要么是false。
- 关系运算符组成的表达式,我们称为关系表达式。a > b
- 比较运算符" == “不能误写成” = "
逻辑运算符
前言
介绍
- 用于连接多个条件(多个关系表达式),最终的结果也是一个boolean值。
一览表
说明逻辑运算规则
- a&b–>&叫逻辑与–>规则:当a和b同时为true,则结果为true,否则为false
- a&&b–>&&叫短路与–>规则:当a和b同时为true,则结果为true,否则为false
- a|b–>|叫逻辑或–>规则:当a和b有一个为true,则结果为true,否则为false
- a||b–>||叫短路或–>规则:当a和b有一个为true,则结果为true,否则为false
- !a–>叫取反或者非运算–>规则:当a为true,则结果为false,当a为false时,结果为true
- a^b–>叫逻辑异或–>规则:当a和b不同时,则结果为true,否则为false
&&和&基本规则
-
名称 语法 特点 短路与&& 条件1&&条件2 两个条件都为true,结果为true 逻辑与& 条件1&条件2 两个条件都为true,结果为true -
&&和&案例演示LogicOperator01.java
package chapter04.test; public class LogicOperator01 { public static void main(String[] args) { int age = 50; if (age > 20 && age < 90) { System.out.println("ok100");//对 } if (age > 20 & age <90) { System.out.println("ok200"); } //区别 int a = 4; int b = 9; if (a < 1 && ++b < 50) { System.out.println("ok300"); } System.out.println("a=" + a + "b=" + b);//4,9 if (a < 1 & ++b < 50) { System.out.println("ok300"); } System.out.println("a=" + a + "b=" + b);//4,10-->代表++b执行了 } }
-
&&和&使用区别
- &&短路与:如果第一个条件为false,则第二个条件不会判断,最终结果为false,效率高
- &逻辑与:不管第一个条件是否为false,第二个条件都要判断,效率低
- 开发中,我们使用的基本使用短路与&&,效率高
||和|基本规则
-
名称 语法 特点 短路或|| 条件1||条件2 两个条件中只要有一个成立,结果为true 逻辑或| 条件1|条件2 只要有一个条件成立,结果为true -
||和|案例演示LogicOperator02.java
-
||和|使用区别
- ||短路或:如果第一个条件为true,则第二个条件不会判断,最终结果为true,效率高
- |逻辑或:不管第一个条件是否为true,第二个条件都要判断,效率低
- 开发中我们基本使用||
!取反和^异或基本规则
-
名称 语法 特点 !非(取反) !条件 如果条件本身成立,结果为false,否则为true -
案例演示InverseOperator.java
-
a^b:叫逻辑异或,当a和b不同时,则结果为true,否则为false
//!取反 System.out.println(60 > 20);//T System.out.println(!(60 > 20));//F //a^b 不同即为真 boolean b = (10 > 1) ^ (3 < 5); System.out.println("b=" + b);//F
练习题
-
答:与x=6,y=6;x=6,y=5;
非x=11 y=6;x=11 y=5。
-
答:注意此处的=是赋值,不是表==的等于
赋值运算符
介绍
- 赋值运算符就是将某个运算后的值,赋给指定的变量。
分类
- 基本赋值运算符 =
- 复合赋值运算符 += , -= , *=, /=, %= 等,重点讲解一个+=,其它的使用是一个道理
a += b;[等价 a = a +b;]
a -= b;[等价 a = a - b;]
案例演示AssignOperator.java
- 赋值基本案例[int num1 = 10]
- +=的使用案例
赋值运算符特点
-
运算顺序从右往左 int num = a + b + c;
-
赋值运算符的左边只能是变量,右边可以是变量、表达式、常量值
int num = a;
int num2 = 78 * 34 - 10;
int num3 = 20;
-
复合赋值运算符等价于下面的效果
比如:a += 3;
等价于a = a + 3;
-
复合赋值运算符会进行类型转换。
byte b = 2; b += 3; //等价 b = (byte)(b + 2)此处涉及了类型的转换 b++;//b = (byte)(b + 1)
三元表达式
基本语法
- 条件表达式 ? 表达式1:表达式2;
运算规则:
-
如果条件表达式为true,运算后的结果是表达式1;
-
如果条件表达式为false,运算后的结果是表达式2;
口诀:一真大师
案例演示TernaryOperator.java
-
int a = 10; int b = 99; int result = a > b ? a++ : b--; System.out.println("res=" + result);//99
-
//变式 int result = a > b ? a++ : b--; System.out.println("result=" + result); System.out.printIn("a=" + a); System.out.println("b=" + b); //10;11;99
使用细节TernaryOperatorDetail.java
-
表达式1和表达式2要为可以赋给接收变量的类型或(可以自动转换或者可以强制转换)
-
三元运算符可以转成if–else语句
int res = a > b ? a++ : --b; -
package chapter04.test; public class TernaryOperatorDetail { public static void main(String[] args) { //1.类型匹配 int a = 3; int b = 8; int c = a > b ? a : b;//类型匹配 int c1 = a > b ? (int)1.1 : (int)3.4;//可以,类型强转 double c2 = a > b ? a : b + 3;//自动转换 //2.本质就是if--else语句 int res = a>b ? a++ : --b; if( a > b) res= a++; else res = --b; } }
课堂练习
-
实现三个数的最大值
-
package chapter04.test; public class TernaryOperatorExercise { public static void main(String[] args) { //实现三个数的最大数 int n1 = 55; int n2 = 33; int n3 = 123; //思路分析 /* 1.先得到n1、n2中的最大数,保存到max1 2.然后再求 max1、n3中的最大数,保存到max2 */ int max1 = n1 > n2 ? n1 : n2; int max2 = max1 > n3 ? max1 : n3; System.out.println("最大数=" + max2); //使用一条语句输出,但可读性较差,推荐使用第一种 //但后面又更好的方法,比如排序!!! int max = (n1 > n2 ? n1 : n2) > n3 ? (n1 > n2 ? n1 : n2) : n3; System.out.println("最大数=" + max); } }
运算符优先级
优先级
- 运算符有不同的优先级,所谓优先级就是表达式运算中的运算顺序。如右表,上一行运算符总优先于下一行。
- 只有单目运算符、赋值运算符是从右向左运算的。
梳理小结:
- ? r–l从right到left
- 用熟即可,不用特意去背
- () {}–>单目运算–>算术运算符–>位移运算符–>比较运算符–>逻辑运算符–>三元运算符–>赋值运算符
标识符
标识符命名规则
标识符概念
- Java 对各种变量、方法和类等命名时使用的字符序列称为标识符
- 凡是自己可以起名字的地方都叫标识符 int num1 = 90;
标识符的命名规则**(必须遵守)**
- 由26个英文字母大小写,0-9,_或$组成
- 数字不可以开头。int 3ab = 1;//错误
- 不可以使用关键字和保留字,但能包含关键字和保留字。
- Java中严格区分大小写,长度无限制。int totalNum = 10; int n = 90;
- 标识符不能包含空格。int a b = 90;//错误
判断下面变量名是否正确
hsp//T
hsp12//T
1hsp//错误-->2.
h-s//错误-->1
x h//错误-->5
h$4//T
class//错误-->关键字
int//错误
double//错误
public//错误
static//错误-->关键字
goto//错误-->保留字
stu_name//T
标识符规范
-
包名:多单词组成时所有字母都小写:aaa.bbb.ccc
//比如com.yuri.www(域名倒置)
-
类名、接口名:多单词组成时,所有单词的首字母大写:XxxYyyZzz
//比如TankShotGame(首字母大写+驼峰原则–>大驼峰)
-
变量名、方法名:多单词组成时,第一个单词首字母小写,第二个单词开始每个单词首字母大写:xxxYyyZzz
//比如tankShotGame(驼峰原则–>小驼峰) -
常量名:所有字母都大写。多单词时每个单词用下划线连接:XXX_YYY_ZZZ
//比如定义一个所得税率TAX_RATE(所有字母大写) -
后面我们学习到类,包,接口,等时,我们的命名规范要这样遵守,更加详细的看文档
关键字(不用背)
定义:被Java语言赋予了特殊含义,用做专门用途的字符串(单词)
特点:关键字中所有字母都为小写
一览表:
保留字
介绍
- Java保留字:现有Java版本尚未使用,但以后版本可能会作为关键字使用。自己命名标识符时要避免使用这些保留字byValue、cast、future、 generic、 inner、operator、outer、rest、var 、goto、const
键盘输入语句
介绍
- 在编程中,需要接收用户输入的数据,就可以使用键盘输入语句来获取。Input.java需要一个扫描器(对象),就是Scanner。
步骤
-
导入该类的所在包,java.util.*
-
创建该类对象(声明变量)
-
调用里面的功能
案例演示
-
要求:可以从控制台接收用户信息(姓名, 年龄,薪水)
-
简单交互
-
package chapter04.test; import java.util.Scanner;//表示把这个包下的scanner类导入这个文件 public class InPut { public static void main(String[] args) { //演示接收用户的输入 //Scanner类表示 简单扫描器,再java.util包中 //1.引入/导入 Scanner类所在的包-->见抬头的import //2.创建Scanner 对象,new 创建一个对象 Scanner scanner = new Scanner(System.in); //3.接收用户的输入,使用 相关的方法 System.out.println("请输入名字"); String name = scanner.next();//接收用户输入 System.out.println("请输入年龄"); int age = scanner.nextInt();//接收用户输入 System.out.println("请输入薪水"); double sla = scanner.nextDouble();//接收用户输入 System.out.println("人的信息如下:"); System.out.println("名字=" + name +" 年龄=" + age + " 薪水=" + sla ); } }
进制
前言
介绍对于整数,有四种表示方式:
- 二进制:0-1,满2进1,以0b或0B开头
- 十进制:0-9,满10进1
- 八进制:0-7,满8进1,以数字0开头表示
- 十六进制:0-9及A(10)-F(15),满16进1,以0x或0X开头表示。此处的A-F不区分大小写。
举例说明BinaryTest.java
-
int n1 = 0b1010; int n2 = 1010; int n3 = 01010; int n4 = 0x10101;
进制图示
进制转换
-
2-8-16–>10
-
10–>2-8-16
-
2–>8-16
-
8-16–>2
具体
1.二进制转换成十进制
规则:从最低位(右边)开始,将每个位上的数提取出来,乘以2的(位数-1)次方,然后求和。
案例:请将0b1011转成十进制的数(0b1011 = ? )
答案:
2.八进制转换成十进制
规则:从最低位(右边)开始,将每个位上的数提取出来,乘以8的(位数-1)次方,然后求和。
案例:请将0234转成十进制的数(0234 = ? )
答案:4 * 8^0 + 3 * 8^1 + 2* 8^2 =4+24+128=156
3.十六进制转换成十进制
规则:从最低位(右边)开始,将每个位上的数提取出来,乘以16的(位数-1)次方,然后求和。
案例:请将0x23A转成十进制的数
答案:10* 16^0 + 3 * 16^1 + 2*16^2 =512
4.十进制转换成二进制
规则:将该数不断除以2,直到商为0为止,然后将每步得到的余数倒过来,就是对应的二进制。
案例:请将34转成二进制 =
答案:反转取余法
5.十进制转换成八进制
规则:将该数不断除以8,直到商为0为止,然后将每步得到的余数倒过来,就是对应的二进制。
案例:131= 0203
6.十六进制转换成二进制
规则:将该数不断除以16,直到商为0为止,然后将每步得到的余数倒过来,就是对应的二进制。
案例:237 = 0xED
7.计算
123转2–>0b 0111 1011
678转8–>01246
8912转16–>0x22D0
8.二转八
规则:从低位开始,将二进制数每三位一组,转成对应的八进制数即可。
案例:请将ob11010101转成八进制
答案:
9.二转十六
规则:从低位开始,将二进制数每四位一组,转成对应的十六进制数即可。
案例:请将ob11010101转成十六进制
答案:
10.八转二
规则:将八进制数每1位,转成对应的一个3位的二进制数即可。
案例:请将0237转成二进制
答案:0b10011111(这里舍弃了高位的0,老师答案有误)
11.十六转二
规则:将十六进制数每1位,转成对应的一个4位的二进制数即可。
案例:0x23B = 0010 0011 1011
二进制在运算中的说明
- 二进制是逢2进位的进位制,0、1是基本算符。
- 现代的电子计算机技术全部采用的是二进制,因为它只使用0、1两个数字符号,非常简单方便,易于用电子方式实现。计算机内部处理的信息,都是采用二进制数来表示的。二进制(Binary)数用0和1两个数字及其组合来表示任何数。进位规则是"逢2进1",数字1在不同的位上代表不同的值,按从右至左的次序,这个值以二倍递增。
位运算
思考题
- 请看下面的代码段,回答a、b、c、d、e结果是多少?
public static void main(String[] args)
int a = 1>>2; //1向右位移2位
int b = -1>>2;//
int c = 1<<2;//
int d = -1<<2;//
int e = 3>>>2;//无符号右移
//a,b,c,d,e结果是多少
System.out.println("a=" + a);
System.out.println("b=" + b);
System.out.println("c=" + c);
System.out.println("d=" + d);
System.out.println("e=" + e);
- 请回答在java中,下面的表达式运算的结果是:(位操作)
~2 = ?//按位取反
2&3 = ?//2按位与3
2|3 = ?
~-5 = ?
13&7 = ?
5|4 = ?
-3^3 = ?//^按位异或
原码、反码、补码-重难点
网上对原码、反码、补码的解释过于复杂,我这里精简几句话(背)
对于有符号的而言:
-
二进制的最高位是符号位:0表示正数,1表示负数(口诀旋转90°,0–>0,1–>-)
-
正数的原码,反码,补码都一样(三码合一)
-
负数的反码=它的原码符号位不变,其它位取反(0–>1,1–>0)
-
负数的补码=它的反码+1,负数的反码=负数的补码-1
-
0的反码,补码都是0
-
java没有无符号数,换言之,java中的数都是有符号的
-
在计算机运算的时候,都是以补码的方式来运算的
-
当我们看运算结果的时候,要看他的原码(重点)
运算
- java中有7个位运算(&、|、^、~、>>、<<和>>>)
&、|、^、~
-
分别是按位与&、按位或|、按位异或^、按位取反~ ,它们的运算规则是:
-
按位与&:两位全为1,结果为1,否则为0
按位或|:两位有一个为1,结果为1,否则为0
按位异或^:两位一个为0,一个为1,结果为1,否则为0
按位取反~:0–>1,1–>0
/*比如:2&3 = ? ~-2 = ? ~2 = ? 2|3 = ? 2^3 = ?*/ public class BitOperatorDetail { //编写一个main方法 public static void main(String[] args) { //推导过程 /* //因为JVM规定int类型为32个bits 1.先得到2的补码-->2的原码00000000 00000000 00000000 00000010 2的补码00000000 00000000 00000000 00000010 2.3的补码-->3的原码00000000 00000000 00000000 00000011 3的补码00000000 00000000 00000000 00000011 3.按位& 00000000 00000000 00000000 00000010 00000000 00000000 00000000 00000011 00000000 00000000 00000000 00000010 &运算后的补码 第一位为0,整数三码合一 运算后的原码也是00000000 00000000 00000000 00000010 4.结果就是2 */ System.out.println(2&3);//2 //推导 //1. 先得到-2的原码10000000 00000000 00000000 00000010 //2. -2的反码 11111111 11111111 11111111 11111101 //3. -2的补码 11111111 11111111 11111111 11111110 //4. ~-2操作 00000000 00000000 00000000 00000001 运算后的补码 //5. 运算后的原码就是00000000 00000000 00000000 00000001 => 1 System . out . println(~-2);//1 //推导 //1. 得到2的补码 00000000 00000000 00000000 00000010 //2. ~2操作 11111111 11111111 11111111 11111101 运算后的补码 //3.运算后的反码 11111111 11111111 11111111 11111100 //4.运算后的原码 10000000 00000000 00000000 00000011 => -3 System . out . println(~2); //-3 //末尾为0就向前借一位当2 } }
-
完成前面的思考题!!!
三个位运算符>>、<<和>>>
-
运算规则:
-
1.算术右移>>:低位溢出,符号位不变,并用符号位补溢出的高位
2.算术左移<<:符号位不变,低位补0
3.>>>逻辑右移也叫无符号右移:运算规则:低位溢出,高位补0
4.特别说明:没有<<<符号 -
应用案例BitOperator02.java
int a = 1>>2; //1 = 00000000 00000000 00000000 00000001 //--> 00000000 00000000 00000000 00000000 本质就是1/2/2=0 相当于删除右侧低位的1,在保留符号位0的同时,在其后一位即左侧高位的第二位用符号位补齐 int c = 1<<2; //00000001-->00000010 本质就是1*2*2=4 相当于保留左侧符号位,删除其后一位,在右侧的低位用0补齐
-
完成前面的案例
3>>2//本质3*2*2-->3*2^2=12 15<<2//本质15/2/2-->15/(2^2)=3
-
建议:掌握讲解即可,不用再深入!
家庭作业
//1.计算下列表达式的结果
10/3 = ?;//3
10/5 = ?;//2
10%2 = ?;//0
-10.5%3 = ?;//a % b 当a是小数时,公式 = a - (int)a / b * b
//原式= -10.5 - (-10)/3 * 3 = -10.5 + 9 = -1.5
//注意:有小数参与的运算时结果是近似值(要用差值之间的精度进行判断)
//2.试说出下面代码的结果
int i = 66;
System.out.println(++i+i);//67+67=134-->先自增再赋值
//3.在Java中,以下赋值语句正确的是
/*
A) int num1 = (int)"18";//F 字符串转基本类用包装类Integer.parseint("18");
B) int num2 = 18.0;//F 类型不匹配
C) double num3 = 3d;//T
D) double num4 = 8;//T
E) int i = 48; char ch = i+1;//F int不能转成char
F) byte b = 19; short s = b+2;//T 自己做错了 此处应该是错误的,因为b+2已经是int类型了,不能再将其转化成short类型
*/
//4.试写出将String转换成double类型的语句,以及将char类型转换成String的语句,举例说明即可
public class convert {
public static void mian(String[] args) {
String s = "18.8";//注意字符串要能转换成double
double d = Double.parseDouble(s);
System.out.println(d);
char c = '哈';
String s2 = c + "";
System.out.println(s2);
}
}