day03-Java语言基础之运算符
今天我们主要学习,各种运算符,包括算术运算符,赋值运算符,关系运算符,逻辑运算符,位运算符和三目运算符,以及最后简单学习了利用Scanner接收键盘输入的代码。
重点:
算术运算符: +(3中含义), /(除数和被除数都是整数时结果丢弃小数位),%, ++及--(理解++和--运算符在变量之前和变量之后的区别)。
赋值运算符:注意复合赋值运算的含义比如:+=,-=,/=, %=等等
关系运算符:注意不要把== 写成 =
逻辑运算符: && 和 ||的短路效果的含义,以及 & | !^四个运算符的含义,最后要注意利用 &&运算符来表示范围的判断, 比如 a>= 3 && a <=10
位运算:熟悉 <<,>>, >>>, &,|,^,这几个位运算符的含义
三目运算符:熟悉三目运算符的格式,及使用
public class Demo1 { public static void main(String[] args) { //关于 默认值 1, 2 默认类型是int long a = 88888888888L; //通过给整数字面量加后缀L或l声明字面量为l // 3.0, 2.1 默认类型double float b = 3.0F; //通过给小数字面量,加f后缀声明,小数字面量的类型是float类型 //关于小数的表示 double c = 314.0; //科学计数法 c = 3.14e2; // 3.14 * 10^2 System.out.println(c); //关于字符的问题 // 编码表,一个字符,要被保存到计算机中,只能以数值的形式 // 一个字符对应的数值,也就是字符和字符对应的数值对应关系,编码表 // ascII码表 // 'a' 97 // 'b' 98 System.out.println('a');//输出结果为a System.out.println('a'=1); //输出结果为98.'a'先转换成int类型,再+1 /* 1.byte,short,char -> int -> long -> float -> double 2.byte,short,char相互之间不转换,他们参与运算首先转换为int类型。 */ System.out.println((char)('a' + 1));//输出结果为b }
1.算术运算符
算术运算符的注意事项:
对于+运算符
加法
正数
字符串拼接: "hello" + "world" ="helloworld"
public class AddOperator { public static void main(String[] args) { //1加法 int a = 1; int b = 2; System.out.println(a + b); //2. 表示正数的正号 a = +1; //3.字符串拼接 // 操作数1 + 操作数2 两个操作数中,只要至少有一个是字符串,+操作执行的就是字符串拼接 System.out.println("hello" + 'a' + 1); // helloa1 System.out.println('a' + 1 + "hello"); // 98hello System.out.println("5+5="+5+5); //5+5=55 System.out.println(5+5+"=5+5");//10=5+5 } }
对于/运算符
整数相除只能得到整数
%
/** * * /: 除法运算 * %: 求余数的操作 */ public class DivideOperator { public static void main(String[] args) { int a = 3; int b = 2; //当参与除法运算的除数和被除数,他们都是整数的时候,此时除法运算的结果, // 会丢弃小数部分,只保留整数部分 int c = a / b; double d = a / b; //1 -> 1.0,这里只是把a/b的结果1转化为double类型 //隐式类型转化 double e = 1.0 * a / b; System.out.println(e); //结果为1.5。1.0默认为double型 // % int f = 5 % 3; //2 System.out.println(f); } }
++和--
(++或--)单独使用效果, 若参与运算,位置不同,效果不同
++: 让一个变量自增1 ,a++ 等价于 a = a + 1
--: 让一个变量的值自减1, b-- 等价于b = b - 1
注意事项:
1. ++,--,他们都既可以放在变量之后(a++ b--), 也可以被放在变量之前(++a, --b)
2. 当++ 或者 --,他们不参与任何其他运算的时候,++或--,在变量前或者变量之后是没有区别的
3. 但是一旦++或者--,参与其他运算的时候,它们就会有一点区别:
对于 ++ 而言:
当++在后的时候,参与运算的时候,首先a原本的值参与运算,a的值再自增1,即 a++ + 1,运算过程相当于先a +1再运算a++
++在前,++a + 1 ,参与运算的时候,首先自增,再参与运算
对于--而言:--在前和--在后,区别与 ++在前和++在后
public class IncAndDes { public static void main(String[] args) {1 //++ int a = 1; a++; System.out.println("a++ = " + a); a = 1; ++a; System.out.println("++a = " + a); //-- int b = 2; b--; System.out.println("b-- = " + b); b = 2; --b; System.out.println("--b = " + b); //++在前和在后的区别 a = 1; int result = a++ + 1; //System.out.println(result); //System.out.println(a); a = 1; result = ++a + 1; //System.out.println(result); //System.out.println(a); //-- b = 2; result = b-- - 1; System.out.println(result); System.out.println(b); b = 2; result = --b - 1; System.out.println(result); System.out.println(b); // a = 4; // 4 + 6 + 60 b = (a++) + (++a) + (a * 10); System.out.println(b); } }
2.赋值运算符
符号:= , +=, -=, *=, /=, %=,其中=为基本的赋值运算符,其他的为扩展的赋值运算符
3.比较运算符
关系运算符的结果只有两种true or false
注意和“=”区分不要把“==”写成“=”
4.逻辑运算符
注意事项:
关于数值范围的描述的表达,比如 1 < a < 10
单“&”与双“&&”的区别(短路)
异或(^) VS 或(|)运算符
/** * 逻辑运算符 * &: true & false = false true & true = true false & true = false false & false = false * 只要至少有一个操作数是false,结果就是false,只有当两个操作数都是true的时候,&运算的结果,才是true * * |: true | false = true true | true = true false & true = true false | false = false * 只要至少有一个操作数是true,结果就是true,只有当两个操作数都是false,|运算的结果采薇false * * !: !true = false !false = true * * 注意事项: 1.关于数值范围的描述的表达,比如 1 < a < 10 异或(^) VS 或(|)运算符 单“&”与双“&&”的区别(短路) * && VS & 都是与运算,他们有什么区别呢? * false 与 (a > b) * * && 与运算比较智能, 当它发现&&运算符的第一个操作数结果已经是false, * 第二个操组数(对应的表达式)不去管他,直接得到结果&&的结果false * * & 这种与运算,比较的死板,即使&第一个操作数,它已经是false,此时它仍然会计算第二个操作数(表达式), * 在把计算好的两个操作数的结果,做与运算,得到最终结果 * * &&: 有短路效果,当第一个操作数为false,直接得出与运算的结果 * * 或运算符只要至少有一个操作数是true,结果就是true * true 或(a == b) * * || * | * * ||或运算比较智能,有短路效果 * * 异或运算 ^: 相同为false, 不同为true * true ^ true = false false ^ false = false * true ^ false = true false ^ true = true * */ public class Demo { public static void main(String[] args) { int a = 2; int b = 3; boolean c = a > b & a++ == 0; System.out.println(a); a = 2; //证明&& 操作符比较智能 c = a > b && a++ == 0; System.out.println(a); //证明||有短路效果 a = 2; c = a < b || a++ == 0; System.out.println(a); //异或运算 c = true ^ false; c = true ^ true; System.out.println(c); //表示一个范围 a = 3; //判断a变量的值是否在[1,10) 1 <= a < 10 //c = 1 <= a < 10; c = a >= 1 && a < 10; //判断变量a的值是否在[1,10) } }
5.位运算符
/** * * 位运算符: 针对变量的二进制位来进行运算 * 移位运算: * a.左移运算符: 3 << 2 = 3 * 2 * 2 = 12 * 左移一位相当于给操作数 * 2(左移之后的结果仍然在,相应数据类型的表示范围之内) * 00000000,00000000,00000000,00000011 * 移动一位 * 0000000,00000000,00000000,000000110 * 在移动一位 * 000000,00000000,00000000,0000001100 -> 12 * * b.带符号的移位: -2 >> 1 , 相当于给操作数除以2(只针对,未溢出切,可以被除尽) * 10000000,00000000,00000000,00000010 -> 补码 11111111,11111111,11111111,11111101 * + 1 * 11111111,11111111,11111111,11111110 * 对于带符号位的右移运算而言:右移运算,高位补符号位 * 111111111,11111111,11111111,1111111 -> 10000000,00000000,00000000,00000000 * +1 * * 10000000,00000000,00000000,00000001 -1 * 不能除尽的情况 * 000000000,00000000,00000000,00000011 -> 0000000000,00000000,00000000,0000001 * * * c. 无符号右移:移位的动作和带符号数一模一样的,右移之后,高位直接填充0, * 无符号右移,同常用来处理正整数,对正整数而言,无符号右移一位相当于除以2 * * &: 只针对二进制的一位 0或者1,只有两个二进制都为1的时候结果为1,其余全为0 * 0 & 1 = 0 0 & 0 = 0 1 & 0 = 0 1 & 1 = 1 * * |: 只有两位全为0的时候结果才为0 * 0 | 1 = 1 0 | 0 = 0 1 | 0 = 1 1 | 1 = 1 * * ^: 相同为0,不同为1 * 0 ^ 1 = 1 0 ^ 0 = 0 1 ^ 0 = 1 1 ^ 1 = 0 * 性质: * 1. 一个数和它自己异或运算的结果:a ^ a = 0 * 2. 0和任何数做异或运算:0 ^ a = a * * ~: 按位取反(包括符号位) * ~6 = -7 * 00000000,00000000,00000000,00000110 * 11111111 11111111 11111111 11111001 -> 10000000,00000000,00000000,00000110 * +1 * 10000000,00000000,00000000,00000111 * */ public class Demo { public static void main(String[] args) { //举例数据溢出 正整数 + 1 -> 负数 // 0111 1111,1111 1111,1111 1111,1111 1111 // +1 // 1000 0000 0000 0000 0000 0000 0000 0000 int a = 0x7fffffff; //int类型所能表示的最大正整数 System.out.println(a + 1); //1000 0000,0000 0000,0000 0000,0000 0000 a = 0x80000000; System.out.println(a); //验证左移 << a = 3; int b = 2; a = a << 2; //如果要将让操作数变成移位之后的结果,必须要赋值才行 System.out.println(a << 2); //验证带符号右移 >> a = -1; //1,xxxxxxxxx, 111111111,111111111,11111111,1111111 System.out.println(a >> 2); //无符号右移 >>> a = -2; // 11111111,11111111,11111111,11111110 -> 无符号右移1位 011111111,11111111,11111111,1111111 //System.out.println(a >>> 1); //2147483647 //验证一下异或运算的性质 a = 90; //异或运算满足交换律 System.out.println(a ^ a); //性质1 System.out.println(a ^ 0); //性质2 System.out.println(~6); } }
面试题:
1.请用最有效率的方式写出计算2乘以8的结果
2.请自己实现两个整数变量的交换
/** * * * 1. 请用最有效率的方式写出计算2乘以8的结果 2. 请自己实现两个整数变量的交换 */ public class Exercise { public static void main(String[] args) { //1.请用最有效率的方式写出计算2乘以8的结果 最有效率的方式? 2 * 8 位运算最为高效的操作 // 2 * 8 = 2 * 2^3 System.out.println(2 << 3); //2.请自己实现两个整数变量的交换(才是开发中常用的) int a = 10; int b = 200; //两个变量的交换 int tmp = a; a = b; b = tmp; System.out.println("a = " + a + "----- b = " + b); //变量交换的实现方式2: //ctrl + alt + l a = 10; b = 200; a = a + b; b = a - b; // a + b - b = a a = a - b; // a + b - a = b System.out.println("a = " + a + "----- b = " + b); //实现方式3: a = 10; b = 200; a = a ^ b; b = a ^ b;// a ^(b ^ b) = a a = a ^ b;// a ^ b ^ a -> a ^ a ^ b System.out.println("a = " + a + "----- b = " + b); //实现方式4 a = 10; b = 200; // (a + b) - a = b a = (a+b) - (b=a); //(b = a) 表达式的值是赋值之后的b的值 System.out.println("a = " + a + "----- b = " + b); } }
6.三目运算符
格式: 关系表达式 ?表达式1 : 表达式2
如果关系表达式结果为为true,运算后的结果是表达式1;
如果关系表达式结果为false,运算后的结果是表达式2;
实例: 用关系表达式判断两数是否相同
练习:三数取大 (目前如果没说数据类型,默认就是int类型的数据)
/** * 关系表达式 ?表达式1 : 表达式2 * 如果关系表达式的结果为true,3目运算的结果,就是表达式1的值 * 如果关系表达式的结果为false,3目运算的结果,就是表达式2的值 * */ public class Demo { public static void main(String[] args) { int a; int b; //使用键盘输入 Scanner sc = new Scanner(System.in); a = sc.nextInt(); b = sc.nextInt(); //用关系表达式判断两数是否相同 String s = a == b ? "两数相等" : "两数不相等"; System.out.println(s); // 3数取大 int c = 100; //两数取大,第三个数和两数中的大者比较,取它们的大者就是最大值 int tmp = a > b ? a : b; int result = tmp > c ? tmp : c; System.out.println("最大的是: " + result); //三目运算的,3数取大的嵌套形式 //int tmp = a > b ? a : b; //int result = tmp > c ? tmp : c; result = (a > b ? a : b) > c ? (a > b ? a : b) : c; System.out.println("最大的是: " + result); } }
7.键盘录入数据
键盘录入数据
我们目前在写程序的时候,数据值都是固定的,但是实际开发中,数据值肯定是变化的,所以,我准备把数据改进为键盘录入,提高程序的灵活性。
如何实现键盘录入数据呢?(目前先记住使用)
导包语句(放到class定义的上面):
import java.util.Scanner;
创建对象
Scanner sc = new Scanner(System.in);
从键盘输入读取数据
int x = sc.nextInt();
import java.util.Scanner; /** * @author zhangshuai@Cskaoyan.onaliyun.com on 2020/2/4. * @version 1.0 * * 如何实现键盘录入数据呢 */ public class Demo { public static void main(String[] args) { //键盘录入数据 必须通过Scanner对象来使用其功能 Scanner sc = new Scanner(System.in); //alt + enter //Scanner strSc = new Scanner(System.in); //读取一行字符串 //通过对象使用scanner的功能接收键盘输入 //读取字符串 //String s = sc.nextLine(); // "hello" String //System.out.println(s); int i = sc.nextInt(); boolean b = sc.nextBoolean(); //它们都默认以空格分隔不同的输入 String s = sc.nextLine(); //以回车作为数据的分隔符 System.out.println(i); System.out.println(b); System.out.println("s = " + s); //用完之后记得关闭 sc.close(); // 推荐做法,如果即要读取普通数据,也要读取nextLine(读取一行字符串),用两个Scanner对象 } }
练习:
1.键盘录入两个数据,并对这两个数据求和,输出其结果
2.键盘录入两个数据,获取这两个数据中的最大值
3.键盘录入三个数据,获取这三个数据中的最大值
4.键盘录入两个数据,比较这两个数据是否相等