Java-Day-4(进度 + 三大流程控制语句)
Java-Day-4
进制
整数
- 二进制:0,1,满二进一,0b 或 0B开头
- 十进制:0 ~ 9,满十进一
- 八进制:0 ~ 7,满八进一,数字 0 开头
- 十六进制:0 ~ 9 及 A / a ( 10 ) ~ F / f ( 15 ),满十六进一,0x 或 0X 开头
十进制 | 十六进制 | 八进制 | 二进制 |
---|---|---|---|
9 | 9 | 11 | 1001 |
10 | A | 12 | 1010 |
11 | B | 13 | 1011 |
12 | C | 14 | 1100 |
13 | D | 15 | 1101 |
14 | E | 16 | 1110 |
15 | F | 17 | 1111 |
16 | 10 | 20 | 10000 |
17 | 11 | 21 | 10001 |
进制转换
-
被转为十进制
-
二进制转十进制:从最低位 ( 右 ) 开始,将每个位上的数提取出来,乘 2 ^ ( 位数 - 1 ) ,然后求和
-
例:0b1011 = 1 * 2 ^ 0 + 1 * 2 ^ 1 + 0 * 2 ^ 2 + 1 * 2 ^ 3
= 1 + 2 + 8
= 11
-
-
八进制转十进制:似上,改为乘 8 ^ ( 位数 - 1 )
- 例:0234 = 4 + 3 * 8 + 2 * 64 = 156
-
十六进制转十进制:似上,改乘 16 ^ ( 位数 - 1 )
- 例:0x23A = 10 + 3 * 16 + 2 * 256 = 570
-
-
十进制转换为
-
十进制转换为二进制:将数不断除以 2,直到商为 0 为止,然后将每次得到的余数倒过来即可
-
例:34 = 0B00100010 ( 100010 — 0B100010 — 0B00100010 )
—> 一个字节是存储的基本单位,一个字节有八位,不够的 0 补
除数 被除数 余数 2 34 ( 倒写此列 ) 2 17 0 2 8 1 ( 17 / 2 = 8 ... 1 ) 2 4 0 2 2 0 2 1 0 1 ( 1 / 2 = 0 ... 1 )
-
-
十进制转换为八进制:似上,改为除以 8
-
例:131 = 0203
除数 被除数 余数 8 131 8 16 3 8 2 0 2
-
-
十进制转换为十六进制:似上,改为除以 16
-
例:237 = 0xED
除数 被除数 余数 16 237 16 14 D ( 13 ) E ( 14 )
-
-
-
二进制转换为
- 二进制转换为八进制:从低位开始,二进制数每三位一组,转成对应的八进制数即可
- 例:0b11010101 = ( 0b 11 010 101 ) = 0325
- 二进制转换成十六进制:似上,改为二进制数每四位一组
- 例:0b11010101 = ( 0b 1101 0101 ) = 0xD5
- 二进制转换为八进制:从低位开始,二进制数每三位一组,转成对应的八进制数即可
-
八进制转换为
- 八进制转换为二进制:将八进制每一位数转换成对应的一个三位的二进制数
- 例:0237 = ( 010 011 111 = 0b 0 1001 1111 ) = 0b10011111
- 八进制转换为二进制:将八进制每一位数转换成对应的一个三位的二进制数
-
十六进制转换为
- 十六进制转换为二进制:将十六进制每一位数转换成对应的四位的二进制数
- 例:0x23B = ( 0x 0010 0011 1011 ) = 0b001000111011
- 十六进制转换为二进制:将十六进制每一位数转换成对应的四位的二进制数
-
计算器中:BIN 二进制;OCT 八进制;DEC 十进制;HEX 十六进制
位运算
计算机内部处理的信息都是采用二进制数来表示的
原码、反码、补码
- 二进制的最高位 ( 最左边 ) 是符号位,0 表整数,1 表负数
- 正数的原码、反码、补码都一样
- 负数的反码 = 其原码符号位不变,其余位置取反
- 负数的补码 = 其反码 + 1,负数的反码 = 其补码 - 1
- 0 的反码、补码都是 0
- java 中的数都是有符号的
- 计算机在运算时,都是以补码的方式来运算的 ( 统一了符号的正负 )
- 但当查看运算结果的时候,是原码方式展示的
位运算符
- 按位与:&( 两位全为 1,结果才为 1 )
- 例:2 & 3
- 2 原码 ( 00000000 00000000 00000000 00000010 ) 转补码,正数不变
- 3 原码 ( 00000000 00000000 00000000 00000011 ) 转补码,正数不变
- & 运算:00000000 00000000 00000000 00000010 转原码不变:得 2
- ——> 2
- 例:2 & 3
- 按位或:| ( 两位中有一位 1,则为 1 )
- 按位异或:^( 两位中一个 1,一个 0 时,结果才为 1 )
- 按位取反:~ ( 0 —> 1,1 —> 0 )
- 例1:~ - 2
- 先得 - 2 的原码 ( 10000000 00000000 00000000 00000010 )
- 想要得补码,得先转反码 ( 11111111 11111111 11111111 11111101 )
- 补码 = 反码 + 1:11111111 11111111 11111111 11111110
- 补码 ~ 取反:00000000 00000000 00000000 00000001
- 则运算后的补码转原码:00000000 00000000 00000000 00000001
- ——> 1
- 例2:~ 2
- 2 的原码,正数等于补码:00000000 00000000 00000000 00000010
- ~ 2 运算:11111111 11111111 11111111 11111101( 负 )
- 运算后补码转原码:负数要补转反,再反转原
- 反码 = 补码 - 1:11111111 11111111 11111111 11111100
- 原码 = 反码 ( 符号不变 ) :10000000 00000000 00000000 00000011
- ——> - 3
- 例1:~ - 2
- 算术右移:>>( 低位溢出,符号位不变,并用符号位补溢出的高位 )
- 例:int a = 1 >> 2( 右移两位 )
- 1:00000000 00000000 00000000 00000001
- 右移两位:00000000 00000000 00000000 00000000 ( 01 )
- 本质是 1 / 2 / 2
- ——> 0
- 例:int a = 1 >> 2( 右移两位 )
- 算术左移:<<( 符号位不变,低位补 0 )
- 例:int b = 1 << 2( 左移两位 )
- 1:...... 00000001
- 左移两位:...... 00000100
- 本质是 1 * 2 * 2
- ——> 4
- 例:int b = 1 << 2( 左移两位 )
- 逻辑右移 ( 无符号右移 ):>>> ( 低位溢出,高位补 0 )
三大流程控制语句
- 顺序控制
- 分支控制
- 循环控制
顺序控制
程序从上到下逐行执行,中间没有任何判断和跳转
分支控制
-
单分支 if
-
if(条件表达式){ 执行代码块; }
-
条件表达式为 true,执行代码块,false 则跳过执行代码块
-
-
双分支
-
if(条件表达式){ 执行代码块1; }else{ 执行代码块2; }
-
条件表达式为 true,执行代码块1,否则执行代码块2
// 判断一个年份是否为闰年 Scanner scanner = new Scanner(System.in); int year = scanner.nextInt(); if((year % 4 == 0 && year % 100 != 0) || year % 400 == 0){...}
-
-
多分支
-
if(条件表达式){ 执行代码块1; }else if{ 执行代码块2; }else{ 执行代码块; }
-
多分支也可以没有else,此时如果都不成立,则无执行入口
-
异常处理机制( 之后涉及 )
-
-
嵌套分支,if 里面加各种 if 分支( 多了可读性会变差 )
-
switch 分支
-
switch(表达式){ case 常量1: 语句块1 break; case 常量2: ... break; default: ... break; }
-
结构上
- break 表示直接退出 switch
- 如果 case1 执行完且没有break,则不用判断直接执行下一个 case2 的语句块,以此类推直到 break,没有就执行到结尾完成switch
- 可穿透,例:case 1: case 2: case 3: ... break; // 1、2、3 同一种显示
- 如果一个 case 都没能匹配上就执行 default
-
使用要求
- 表达式数据类型应和 case 后的常量一致,或者能自动转换成可比较的类型( 比如输入字符 char,常量可以是 int )
- switch 里的表达式的返回值必须是:byte、short、int、char、String、enum ( 枚举 ),例如小数的话就会报错,必要情况下只能自行强转先
- case 的必须是常量 / 常量表达式,不能是变量
- 语句中也可以没有 default
-
循环控制
-
for 循环控制
-
for(循环变量初始化; 循环条件; 循环变量迭代){ 循环操作(可以多条语句); }
-
循环变量初始化 —> 循环条件 T —> 循环操作 —> 循环变量迭代 —> 循环条件 T ...... 循环条件 F —> for循环结束
-
循环条件是返回布尔值的表达式
-
for( ; 循环判断条件 ; ) 中的初始化和变量迭代可以省略写外面
// 在循环过后还想使用原本的i,就把i写外面 int i = 1; // i写for里面就只能用在循环里面 for( ; i <= 10; ){ i++; // .... } for(;;){ } // 表示一个无限循环,死循环
-
循环初始值可以有多条初始化语句,但要求类型一样,而且中间用逗号隔开
-
循环条件只有一条
循环变量迭代也可以有多条变量迭代语句,中间用逗号隔开
-
while 循环控制
-
while(循环条件){ 循环体(语句); 循环变量迭代; }
-
-
do...while 循环控制
-
do{ 循环体(语句); 循环变量迭代; }while(循环条件);
-
先执行再判断,不管什么情况都至少执行一次
-
与 while 相比,最后是有一个分号的
-
多重循环控制
-
各种循环控制语句嵌套,只有内层循环 false 后,才结束外层的当次循环
-
化繁为简 —> 逐步搭建 —> 变量替代定数 ( 代码优化,便于修改 )
-
经典打印金字塔
// 金字塔 // * // *** // ***** // ******* // ********* for(int i = 1; i <= 5; i++){ for(int j = 1; j < 5 - i; j++){ System.out.print(" "); } for(int z = 1; z <= 2 * i - 1; z++){ System.out.println("*"); // print 加上 ln 就自动换行 } } // 空心金字塔 // * // * * // * * // * * // ********* int tol = 5; for(int i = 1; i <= tol; i++){ for(int j = 1; j < tol - i; j++){ if(j == 1 || j == 2 * i - 1 || j == tol){ System.out.print("*"); }else{ System.out.print(" "); }
跳转控制语句
break 使用
(int)(Math.random() * 100) + 1; //1 ~ 100的随机数
// Math.random():返回带正号的 double 值,该值大于等于 0.0 且小于 1.0,即 [ 0.0, 1.0 ),注意:取不到后面的最大的那个数
for(){
if(){ break; }
}
System.out.println("break 退出 for 循环,继续代码执行")
-
break 语句出现在多层嵌套中时,可以通过标签指明要终止的是哪一层语句块
lable1: // 标签自定义 for(..; ..; ..){ lable2: for(..; ..; ..){ if(){ break lable1; } //break指到哪就退出到哪 } }
-
实际开发中尽量不要用标签 lable,可读性会变差
-
break 没有指定标签,默认退出最近的循环体
continue 使用
-
用于结束本次循环 ( 循环内后面代码直接跳过不管 ),继续执行下一次循环
-
同上述 break 也可以设标签
return 使用
- 使用在方法里面时,表示跳出所在整个方法,如果在 main 里,就表示退出程序
练习:
// 水仙花数练习
Scanner scanner = new Scanner(System.in);
while(true){
int i = scanner.nextInt();
int a = i % 10;
int b = i / 10 % 10; // i % 100 /10
int c = i / 100 % 10; // i / 100
if(i == a * a * a + b * b * b + c * c * c ){
System.out.println(i + "是水仙花数");
}else{
System.out.println(i + "就不是哩");
}
}
// 1 + 1/2 + 1/3 + 1/4 + ... + 1/100 = ?
// int sum = 0; (错)
double sum = 0;
int k = -1;
for(int i = 1; i <= 100; i++){
k = -1 * k;
// sum += k * (1 / i); (错)
sum += k * (1.0 / i);
}
System.out.println(sum);
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?