# zb_java0719 **Repository Path**: climpeaker/zb_java0719 ## Basic Information - **Project Name**: zb_java0719 - **Description**: 计算机基础补充:原码、反码、补码 运算符 - **Primary Language**: Java - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 16 - **Created**: 2018-07-19 - **Last Updated**: 2020-12-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # zb_java0719 # 教学目标 1.计算机基础补充:原码、反码、补码 2.运算符 # 课堂笔记 ## 计算机基础:原码、反码、补码 原码、反码、补码主要是计算机中二进制对负数的兼容; 1.原码 使用二进制表示一个数就是这个数的原码; 计算机二进制中的负数的表示,采用最高位(最左侧)作为符号位,1表示负数,0表示整数; 正数的原码就是其二进制的数; 负数的原码: 将负数的绝对值使用二进制表示以后,将最高位变为1,这就是负数原码; 例如: -3 原码: 1000 0011 因为cpu只会进行加法运算,所以需要将减法变为加法,但是计算机使用原码进行运算时,运算结果是错误的; 例如: 2-5 转换加法 2+(-5) 这时,用原码进行计算,结果是错误的; 2 原码 0000 0010 -5 原码 1000 0101 相加 1000 0111 原码结果是 -7 基于以上原因: 提出了补码的概念,补码的作用就是将减法转换为加法进行运算; 补码求法: 正数的补码和原码一样。 负数的补码:原码的最高符号位不变,其他各位取反+1; 求法二:反码+1; 补充:负数的补码继续进行求补运算得到是原码; 反码: 存在价值:为了求补码,是一个中间过程值。 正数的反码和原码一样; 负数的反码:原码的最高符号位不变,其他各位取反; 示例:运用补码计算 2-5 2 原码 0000 0010 补码 0000 0010 -5 原码 1000 0101 补码 1111 1011 进行加法运算 1111 1101 (计算结果还是补码) 还原为原码: 1000 0011 (原码:-3) ###### 定律:计算机中所有的数都是以补码的形式存在的。【计算机中的负数是以补码的形式存在的】【正数的原码、反码、补码一样】 ## 3 位运算符 ### 3.4 移位运算 是对二进制的数的每一位进行运算;(参与运算的数是二进制中的位bit) 运算符: ~ & | ^ >> << >>> 语法: << 左移运算:最高位符号位不变,其他各位向左移动N位,右侧空余的位数补0; 等价于:该数*2的N次方; >> 右移运算:最高符号位不变,其他各位向右移动N位,左侧空余位数补符号位;【符号位是0补0,符号位是1补1】 等价于:该数/2的N次方; >>>带符号位的右移:最高符号位也参与移位,所有位数全部向右移动N位,左侧空余位数补0; 等价于:该数/2的N次方;注意,该运算只对正数有意义,对负数没有意义; 位移运算效率要比运算乘法、除法效率高; 代码[com.yuw.ch2.opt.Test01]: ```java /** * 位移运算 */ private static void test01() { // 定义一个变量 int iVal10 = 3; int iVal20 = 128; // 左移运算 int iVal11 = iVal10 << 3;// 等价于 iVal*2的3次方 24 System.out.println("iVal10<<3:" + iVal11); // 右移运算 int iVal21 = iVal20 >> 3; // 等价于 iVal21/2的3次方 System.out.println("iVal20>>3:" + iVal21); } ``` 位运算应用:采用异或位运算交换两个数的值。【优点:不需要借助第三个临时变量】 代码[com.yuw.ch2.opt.Test01]: ```java /** * 位运算应用:不借助第三个变量,交换两个变量的值 */ private static void test02() { int i = 2; int j = 3; System.out.println("交换前:i=" + i + ",j=" + j); // 交换两个变量的值 i ^= j; j ^= i; i ^= j; System.out.println("交换后:i=" + i + ",j=" + j); } /** * 位运算应用:借助第三个变量,交换两个变量的值 */ private static void test021() { int i = 2; int j = 3; System.out.println("交换前:i=" + i + ",j=" + j); // 交换两个变量的值 // 定义一个临时变量 int temp = i; i=j; j=temp; System.out.println("交换后:i=" + i + ",j=" + j); } ``` ## 4 逻辑算符 ### 4.1 逻辑运算语法 逻辑运算的运算符: ! && || 逻辑运算的操作数是布尔类型; 逻辑运算的结果也是布尔类型; 逻辑运算优先级: 非>与>或 !运算:一元运算符 true 变 false false 变 true &&与运算:二元运算符 T && T = T T && F = F F && T = F F && F = F 总结:只有两个操作数都为T时,才为T,其他情况为F; ||或运算:二元运算符 T || T = T T || F = T F || T = T F || F = F 总结:只有两个操作数都为F时,才为F,其他情况为T; 代码[com.yuw.ch2.opt.Test01]: ```java /** * 逻辑运算 */ private static void test03() { // 定义变量 int i0 = 0; int i1 = 1; int i2 = 2; boolean isOk1 = ++i0 > i1++ && ++i1 > i2; // false i0=1; i1=3 i2=2 System.out.println("isOk1=" + isOk1); System.out.println("i0=" + i0 + ",i1=" + i1 + ",i2=" + i2); // 发生了逻辑短路 } ``` ### 4.1 逻辑运算短路 逻辑短路: 当多个表达式进行连续的与运算时,从左往右如果某个表达式的结果是false,则与运算结果为false, 同时该表达式之后的表达式不再参与运算,这就是逻辑与短路。 逻辑或短路: 当多个表达式进行连续的或运算时,从左往右如果某个表达式的结果是true,则整个或运算结果为true, 同时该表达式之后的表达式不再参与运算,这就是逻辑或短路。 混合逻辑短路: 逻辑与和逻辑或进行运算时,可以在与运算或者或运算都发生逻辑短路; 代码[com.yuw.ch2.opt.Test01]: ```java /** * 逻辑运算 */ private static void test03() { // 定义变量 int i0 = 0; int i1 = 1; int i2 = 2; boolean isOk1 = ++i0 > i1++ && ++i1 > i2; // false i0=1; i1=2 i2=2 // 发生逻辑与短路 System.out.println("isOk1=" + isOk1); System.out.println("i0=" + i0 + ",i1=" + i1 + ",i2=" + i2); // 发生了逻辑短路 System.out.println("==========================="); // 重新初始化赋值 i0 = 0; i1 = 1; i2 = 2; // 或短路 boolean isOk2 = ++i0 >= i1++ || ++i1 > i2; // true i0=1; i1=2 i2=2 // 发生逻辑或短路 System.out.println("isOk2=" + isOk2); System.out.println("i0=" + i0 + ",i1=" + i1 + ",i2=" + i2); // 发生了逻辑短路 System.out.println("==========================="); i0 = 0; i1 = 1; i2 = 2; int i3 = 4; int i4 = 5; // 1+1+1+1+1+2+3+3*4+4*5 从左往右开始执行 // 混合逻辑短路 F T T T(发生短路) boolean isOk3 = ++i0 > i1++ || ++i1 > i2 && i4 > i3++ || ++i3 > i4++ || i4 > i3 && i3-- > --i4; // true // i0 =1 ,i1=3, i2 = 2,i3 =5 ,i4 = 5 System.out.println("isOk3=" + isOk3); System.out.println("i0=" + i0 + ",i1=" + i1 + ",i2=" + i2 + ",i3=" + i3 + ",i4=" + i4); // 发生了逻辑短路 // 从左往右 boolean isOk4 = (++i0 > i1++ || ++i1 > i2) && i4 > i3++; } ``` ## 5 表达式运算优先级 记住:教材P38页表; 自增、自减 > 乘除求余 > 加减 > 位移 > 比较运算 > 位运算 > 逻辑运算 > 赋值运算 ## 6 补充:自增自减运算一些特殊情况【暂时不做掌握要求】 代码[]: ```java /** * 自增自减运算一些特殊情况展示 */ private static void test04() { int i = 1; int j = 1; int k = (i++) + j; // ++ -- 是从右往左结合 System.out.println("k=" + k); int k1 = i + (++j); System.out.println("k1=" + k1); System.out.println("========================"); i = 1; i = i++; // i++ 表达式是1 i的值变为2 /* * 因为都是变量i在进行计算,计算过程: * 1、先计算表达式 i++ 的值为1,将该表达式的值存入一个临时变量中; * 2、因为运行了 表达式 i++,所有i的值变为2; * 第1、2步在执行表达式 i++的值; * 3、因为还有一步 = 赋值运算,需要将表达式 i++的值赋值给变量i, * 将第1步中缓存在临时变量中表达式 i++的值,赋值运算给变量i, * 这是,变量i的值有重新赋值为1. * */ System.out.println("i=" + i); System.out.println("==================="); /* * 原则:代码的编译执行时从左往右执行的; */ i = 1; i += i++; // 表达式 i++ 参与运算,代码执行时从左往右进行 System.out.println("i=" + i); // 2 // 等价于 i = 1; i = i + i++; /* * 解析:程序是从左往右执行的; * =右边,第一个i解析时的值为1; * 继续执行,i++表达式的值为1,表达式执行完后变量i的值为2,但是不会更新上一步解析的变量i的值 */ System.out.println("i=" + i); // 2 i = 1; i = i++ + i; /* * 同理,推测 * =号右边表达式的值,i++为1,然后变量i的值为2; * 继续执行,解析加号后面的i,此时i的值为2 */ System.out.println("i=" + i); // 3 } ``` ###### scanner类的应用:从控制台输入信息到系统中: 代码[com.yuw.ch2.opt.Test02]: ```java public static void main(String[] args) { /* * 练习使用Scanner工具类从控制台获取输入的内容 */ // 苹果数 int appleNum = 0; // 学生数 int stuNum = -1; // 可分配的苹果数 double stuApples = -1; // 创建一个Scanner类,从控制台录入信息 Scanner sc = new Scanner(System.in); // 信息录入提示 System.out.println("请输入篮子里有几个苹果:"); // 从控制台获取录入的苹果的数值,需要从键盘录入 appleNum = sc.nextInt(); System.out.println("请录入小朋友的人数:"); stuNum = sc.nextInt(); // 计算每个小朋友可以分配的苹果数 stuApples = 1.0 * appleNum / stuNum; // 输出计算结果 System.out.println("每个小朋友获得" + stuApples + "个苹果。"); } ``` ## CH3 流程控制 ### 3.1 程序的流程分裂 程序的流程主要分为:顺序流程、分支流程、循环流程; 顺序流程:从上往下、从左往右依次执行; 分支流程:根据条件选择不同的分支进行执行; 循环流程:重复进行某一项操作【重复循环操作】; ### 3.2 分支流程 #### 3.2.1 分支流程 分支流程分为:单选分支流程和多选分支流程; ##### 3.2.1.1 单选分支流程 单选分支流程主要由if语句进行实现 if语句有单分支、双分支、多分支if语句。 if语句中可以继续嵌套if语句; 单分支if语句: 语法: if(条件判定表达式){ if语句体; } 执行流程: (1)先执行条件判定表达式,如果表达式结果true,则执行if语句体; 否则,不执行if语句体,而直接执行if语句之后的其他代码; 注意: 条件判定表达式的结果必须为boolean类型; if语句后面编程规范要求使用一对{}表明if语句体的范围; 如果不写{}则紧跟if后面的第一条语句作为if的语句体; 所以编程规范要求:即便if语句体为空,也要写上{} 代码[com.yuw.ch2.opt.Test03]: ```java /** * if分支语句流程--单分支 */ private static void test01() { // 单分支选择 Scanner sc = new Scanner(System.in); System.out.println("请输入你的成绩:"); // 接收输入的值 int iScore = sc.nextInt(); // 判定成绩的等级 if (iScore >= 60) { ; System.out.println("恭喜你,好歹及格了"); } System.out.println("你的成绩评级已经结束。。。"); } ``` 双分支if语句: 语法: if(条件判定表达式){ if语句体; }else{ else语句体; } 执行流程: (1)先执行条件判定表达式,如果表达式结果true,则执行if语句体; 否则,执行else语句体. 注意: if语句体和else语句体永远不可能同时执行; 代码[com.yuw.ch2.opt.Test03]: ```java /** * if分支语句流程--双分支 */ private static void test02() { // 单分支选择 Scanner sc = new Scanner(System.in); System.out.println("请输入你的成绩:"); // 接收输入的值 int iScore = sc.nextInt(); // 判定成绩的等级 if (iScore >= 60) { System.out.println("恭喜你,好歹及格了"); }else{ System.out.println("很不幸,没有及格,请继续努力"); } System.out.println("你的成绩评级已经结束。。。"); } ``` 多分支if语句: 语法: if(条件判定表达式){ if语句体; }else if(条件判定表达式2){ if语句体2; }else if(条件判定表达式n){ if语句体n; }else{ else语句体; } 执行流程: (1)从上往下依次执行条件判定表达式,如果那个分支的条件表达式结果true,则执行该分支的if语句体; 该分支执行完成之后,则if-slse语句块执行结束; (2)如果所有的分支的条件判定表达式都不为true,则执行else语句体,然后结束. 注意: else分支可以有,也可以没有; 代码[com.yuw.ch2.opt.Test03]: ```java /** * if分支语句流程--多分支 */ private static void test03() { // 单分支选择 Scanner sc = new Scanner(System.in); System.out.println("请输入你的成绩:"); // 接收输入的值 int iScore = sc.nextInt(); // 判定成绩的等级 if (iScore >= 90) { System.out.println("恭喜你,获得优秀等级"); }else if(iScore>=80){ System.out.println("恭喜你,获得了优良等级"); }else if(iScore>=70){ System.out.println("恭喜你,获得了中等等级"); }else if(iScore>=60){ System.out.println("恭喜你,好歹及格了"); }else{ System.out.println("很不幸,没有及格,请继续努力"); } System.out.println("你的成绩评级已经结束。。。"); } ``` #### 参与贡献 1. Fork 本项目 2. 新建 Feat_xxx 分支 3. 提交代码 4. 新建 Pull Request #### 码云特技 1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md 2. 码云官方博客 [blog.gitee.com](https://blog.gitee.com) 3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解码云上的优秀开源项目 4. [GVP](https://gitee.com/gvp) 全称是码云最有价值开源项目,是码云综合评定出的优秀开源项目 5. 码云官方提供的使用手册 [http://git.mydoc.io/](http://git.mydoc.io/) 6. 码云封面人物是一档用来展示码云会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)