文章目录
前言
本篇文章是韩顺平老师课程P63-P103(第四章:运算符)重点内容的详细总结,仍然是偏理论的东西,为后面编程打好基础。
- 算术、关系、逻辑、赋值、三元运算符的介绍、使用、练习
- 标识符与关键字
- 进制介绍及转换
- 原码补码反码的介绍和计算
- 位运算
一、运算符(算术、关系、逻辑、赋值、三元)
- 运算符介绍:是一种特殊的符号,用以表示数据的运算、赋值和比较等
1. 算术运算符
- 除法 “/”
System.out.println(10 / 4); //java中是2,因为 10 和 4 都是整数
System.out.println(10.0 / 4); //java中是2.5,因为 10 是double类型
double d = 10 / 2; //结果是5.0,因为是double类型
- 模 “%”
System.out.println(10 % 4); //2
System.out.println(-10 & 4); //-2
//在Java中,取模的本质 看一个公式 a % b = a - a / b *b
// -10 % 3 => -10 - (-10) / 3 * 3 = -10 + 9 = -1
// 10 % -3 => 10 - 10 / (-3) * (-3) = 10 - 9 = 1
System.out.println(10 & -3); //1
System.out.println(-10 & -3); //-1
- 自增"++"
- 作为独立语句使用,结果相同
int i = 10;
i++;//自增 等价于 i = i + 1; => i = 11
++i;//自增 等价于 i = i + 1; => i = 12
System.out.println("i=" + i);//12
- 作为表达式使用
/*
作为表达式使用
前++:++i 先自增后赋值
后++:i++先赋值后自增
*/
int j = 8;
//int k = ++j; //等价 j=j+1;k=j;
int k = j++; // 等价 k =j;j=j+1;
System.out.println("k=" + k + "j=" + j);//8 9
- 细节
- 对于除号“/”,它的整数和小数除是有区别的:整数之间做除法时,只保留整数部分而舍弃小数部分。
- 当对一个数取模时,可以等价a%b=a-a/b*b,这样我们可以看到取模的一个本质运算。
- 当自增当作一个独立语言使用时,不管是 i++还是 ++i,都是一样的,等价。
- 当自增当作一个表达式使用时
- j = ++i 先自增后赋值
- j = i++ 先赋值后自增
- –, +, -, * 都是一个道理,完全可以类推
2. 关系运算符(比较运算符)
- 介绍
- 关系运算符的结果都是boolean类型,要么是true,要么是false
- 关系表达式 经常用在 if 结构的条件中或循环结构的条件中
- 使用
//演示关系运算符的使用
public class RelationalOperator {
//编写一个 main 方法
public static void main(String[] args) {
int a = 9; //老韩提示: 开发中,不可以使用 a, b
int b = 8;
System.out.println(a > b); //T
System.out.println(a >= b); //T
System.out.println(a <= b); //F
System.out.println(a < b);//F
System.out.println(a == b); //F
System.out.println(a != b); //T
boolean flag = a > b; //T
System.out.println("flag=" + flag);
}
}
- 细节
- 关系运算符的结果都是 boolean 型,也就是要么是 true,要么是 false。
- 关系运算符组成的表达式,我们称为关系表达式。 a > b
- 比较运算符**“==“不能误写成”=”**
3. 逻辑运算符
- 用于连接多个条件(多个关系表达式),最终的结果也是一个Boolean值
- &&和&的区别:
- &&短路与:如果第一个条件为false,则第二个条件不会判断,效率高
- a&&b : 当 a 和 b 同时为 true ,则结果为 true,否则为 false
- &逻辑与:不管第一个是不是为false,第二个都会判断执行,效率低
- a&b : 当 a 和 b 同时为 true ,则结果为 true, 否则为 false
- &&短路与:如果第一个条件为false,则第二个条件不会判断,效率高
/**
* 演示逻辑运算符的使用
*/
public class LogicOperator01 {
//编写一个 main 方法
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;
//对于&&短路与而言,如果第一个条件为 false ,后面的条件不再判断
//对于&逻辑与而言,如果第一个条件为 false ,后面的条件仍然会判断
if(a < 1 & ++b < 50) {
System.out.println("ok300");
}
System.out.println("a=" + a + " b=" + b);// 4 10
}
}
- ||和|的区别:
- ||短路或:如果第一个条件为true,则第二个条件不会判断,最终结果为true,效率高
- a||b : 当 a 和 b ,有一个为 true ,则结果为 true,否则为 false
- |逻辑或:不管第一个是不是为true,第二个都会判断执行,效率低
- a|b : 当 a 和 b ,有一个为 true ,则结果为 true,否则为 false
- ||短路或:如果第一个条件为true,则第二个条件不会判断,最终结果为true,效率高
public class LogicOperator02 {
//编写一个 main 方法
public static void main(String[] args) {
int age = 50;
if(age > 20 || age < 30) {
System.out.println("ok100");
}
//&逻辑与使用
if(age > 20 | age < 30) {
System.out.println("ok200");
}
//看看区别
//(1)||短路或:如果第一个条件为 true,
//则第二个条件不会判断,最终结果为 true,效率高
//(2)| 逻辑或:不管第一个条件是否为 true,第二个条件都要判断,效率低
int a = 4;
int b = 9;
if( a > 1 || ++b > 4) { // 可以换成 | 测试
System.out.println("ok300");
}
System.out.println("a=" + a + " b=" + b); //4 10
}
}
- !和^的区别:
- !非:取反,真变假,假变真
- !a : 当 a 为 true, 则!a结果为 false;当 a 为 false 时,!a结果为 true
- ^逻辑异或:当 a 和 b不同时,结果为true;否则为false
- !非:取反,真变假,假变真
// ! 和 ^ 案例演示
public class InverseOperator {
//编写一个 main 方法
public static void main(String[] args) {
//! 操作是取反 T -> F , F -> T
System.out.println(60 > 20); //T
System.out.println(!(60 > 20)); //F
//a^b: 叫逻辑异或,当 a 和 b 不同时,则结果为 true, 否则为 false
boolean b = (10 > 1) ^ ( 3 > 5);
System.out.println("b=" + b);//T
}
}
4. 赋值运算符
赋值运算符就是将某个运算后的值,赋给指定的变量。
- 分类
- 基本赋值运算符 =
- 复合赋值运算符 *+= -= = /= %= 等
a += b; [等价 a = a + b; ]
a -= b; [等价 a = a - b; ]
- 特点
- 顺序从右往左
- 赋值运算符的左边只能是变量,右边可以是变量、表达式、常量值
int num = 20; int num2= 78 * 34 - 10; int num3 = a;
- 复合赋值运算符等价于下面的效果
a+=3;等价于 a=a+3; 其他类推
- 复合运算符会进行类型转换
public class AssignOperator {
//编写一个 main 方法
public static void main(String[] args) {
int n1 = 10;
n1 += 4;// n1 = n1 + 4
System.out.println(n1); // 14
n1 /= 3;// n1 = n1 / 3
System.out.println(n1); // 4
//复合赋值运算符会进行类型转换
byte b = 3;
b += 2; // 等价 b = (byte)(b + 2);
b++; // b = (byte)(b+1);
}
}
5. 三元运算符Ternary Operator
- 基本语法:条件表达式 ? 表达式1 : 表达式2 ;
- 运算规则
- 如果条件表达式为true,运算后的结果是表达式1
- 如果条件表达式为false,运算后的结果是表达式2
//三元运算符使用
public class TernaryOperator {
//编写一个 main 方法
public static void main(String[] args) {
int a = 10;
int b = 99;
// 解读
// 1. a > b 为 false
// 2. 返回 b--, 先返回 b 的值,然后在 b-1
// 3. 返回的结果是 99
int result = a > b ? a++ : b--;
System.out.println("result=" + result);
System.out.println("a=" + a);
System.out.println("b=" + b);
}
}
- 细节
-
表达式1和表达式2要为可以赋给接收变量的类型(或可以自动转换)
int a = 3;
int b = 8;
int c = a > b ? (int)1.1 : (int)3.4;//可以的
double d = a > b ? a : b + 3;//可以的,满足 int -> double
-
三元运算符可以转成 if–else 语句
int res = a > b ? a++ : --b;
if ( a > b) res = a++;
else res = --b;
-
二、运算符优先级
- 一览表,不需要背,使用多了就记住了
- 只有单目运算符、赋值运算符是从右向左运算的。
三、标识符规范与关键字
1.标识符命名规则和规范
- 概念
- Java对各种变量、方法和类等命名时使用的字符序列称为标识符
- 凡是自己可以自己起名字的地方都叫标识符
- 命名规则
- 由28个英文字母大小写,0-9,_或$组成
- 数字不可以开头
- 不可以使用关键字和保留字,但能包含关键字和保留字
- Java中严格区分大小写,长度无限制
- 标识符不能有空格
- 命名规范
- 包名:多单词组成时所有字母都小写:aaa.bbb.ccc
比如 com.hsp.crm
- 类名、接口名:多单词组成时,左右的单词首字母大写:XxxYyyZzz[大驼峰]
比如TankShotbGame
- 变量名、方法名: 多单词组成时,第一个单词首字母小写,第二个单词开始每个单词首字母大写:xxxYyyZzz [小驼峰,简称驼峰法]
tankShotGame
- 常量名: 所有字母都大写。多单词时每个单词用下划线_连接:XXX_YYY_ZZZ
比如,定义一个所得税率 TAX_RATE
- 后面学到 类,包,接口等,命名的规范要遵守,详情见文档(在老韩资料包里面)
- 包名:多单词组成时所有字母都小写:aaa.bbb.ccc
2. 关键字
- 定义:被Java语言赋予了特殊含义,用作专门用途的字符串
- 特点:关键字中的所有字母都是小写
3. 保留字
现有Java版本尚未使用,但以后版本可能会作为关键字使用;自己命名标识符时要避免使用这些保留字: byValue、cast、future、 generic、 inner、 operator、 outer、 rest、 var 、 goto 、const
四、键盘输入
- 在编程中,接收用户输入的数据,就可以使用键盘输入语句来获取
- 步骤
- 导入该类的所在包, java.util.*
- 创建该类对象(声明变量)
- 调用里面的功能
- char 类型输入
char gender = scan.next().charAt(0);
- scan.next 和 scan.nextLine的区别
Scanner scan = new Scanner(System.in);//输入Tom Blanco
String name = scan.next(); //遇到空格就结束 只输出Tom
String name = scan.nextLine();//读取整行 输出 Tom Blanco
五、进制介绍转换,原码补码和反码(程序员的基本功)
1. 进制
- 对于整数,有四种表示方式
- 进制的转换
- 第一组(XX转十) 从最低位开始,将每个位上的数提取出来,乘以X的(位数-1)次方,然后求和
- 二转十 例子:0b1011 = (1 * 20) + (1 * 21) + (0 * 22) + (1 * 2 3) = 11 = 10
- 八转十
- 十六转十
- 第二组 (十转XX)
- 十转二 将该数不断除以二,直到商为零为止,然后将每步得到的余数倒过来
- 十转八
- 十转十六
- 第三组(二转XX)
- 二转八 从低位开始,将二进制每三位一组,转成对应的八进制数即可
- 二转十六 从低位开始,将二进制每四位一组,转成对应的十六进制数即可
- 第四组(XX转二)
- 八转二 将八进制的每一位,转成对应的一个三位的二进制数
- 十六转二 将十六进制的每一位,转成对应的一个四位的二进制数
- 第一组(XX转十) 从最低位开始,将每个位上的数提取出来,乘以X的(位数-1)次方,然后求和
2. 原码 反码 补码
对于有符号的数而言:
- 二进制的最高位十符号位:0表示正数,1表示负数(0->0 1->-1)
- 正数的原码、反码、补码都是一样的(三码合一)
- 负数的反码=它的原码符号位不变,其他位取反(0->1 1->0)
- 负数的补码=它的反码+1,负数的反码=负数的补码-1
- 0的反码,补码是0
- Java没有无符号数
- 计算机运算的时候,都是以补码的形式来运算(将正负数统一起来)
- 当我们看运算结果的时候,要看它的原码
六、位运算
Java中有7个运算符(&、|、^、~、>>、<< 和 >>>)
- 计算 2&3
//推导过程
//1.先得到-2的原码
// 10000000 00000000 00000000 00000010
//2.得到-2的反码(符号位不变)
// 11111111 11111111 11111111 11111101
//3.得到-2的补码 (反码+1)
// 11111111 11111111 11111111 11111110
//4.~的操作:取反操作
// 00000000 00000000 00000000 00000001
//5.运算后的原码
// 00000000 00000000 00000000 00000001(是正数)
//6.换算成十进制 -> 1
System.out.println(~-2); //1
- 计算 ~-2
//推导过程
//1.先得到-2的原码
// 10000000 00000000 00000000 00000010
//2.得到-2的反码(符号位不变)
// 11111111 11111111 11111111 11111101
//3.得到-2的补码 (反码+1)
// 11111111 11111111 11111111 11111110
//4.~的操作:取反操作
// 00000000 00000000 00000000 00000001
//5.运算后的原码
// 00000000 00000000 00000000 00000001(是正数)
//6.换算成十进制 -> 1
System.out.println(~-2); //1
- 计算 ~2
//推导过程
//1.先得到2的原码
// 00000000 00000000 00000000 00000010
//2.得到2的补码
// 00000000 00000000 00000000 00000010
//3.~的操作:取反操作
// 11111111 11111111 11111111 11111101
//4.算出2补码的反码 (反码=补码-1)
// 11111111 11111111 11111111 11111100
//5.运算后的原码
// 10000000 00000000 00000000 00000011
//6.换算成十进制 -> -3
System.out.println(~2); // -3
位运算符(没有 <<<符号)
- int a = 1 >> 2;
xxxxxxxxxx int a = 1 >> 2; //(算术右移)
// 1 => 00000000 00000000 00000000 00000001 把后两位01扔出去
// 00000000 00000000 00000000 00000000 01 本质是1/2/2 = 0
- int b = 1 << 2;
int a = 1 << 2; //(算术左移)
// 1 => 00000001 把后两位01扔出去
// 00000010 -> 00000100 本质是1*2*2 = 4
总结
本篇文章是韩顺平老师课程P63-P103(第四章:运算符)重点内容的详细总结,仍然是偏理论的东西,为后面编程打好基础。
- 算术、关系、逻辑、赋值、三元运算符的介绍、使用、练习
- 标识符与关键字
- 进制介绍及转换
- 原码补码反码的介绍和计算
- 位运算