数组 与 循环Arrays and Loops

数组Arrays

什么是

一堆同类型变量

案例对比

使用前
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
int number = Console.readInt(); int digit1, digit2, digit3; digit1 = number % 10;number = number / 10; digit2 = number % 10;number = number / 10; digit3 = number % 10;number = number / 10; Console.println(digit3);Console.println(digit2);Console.println(digit1);
使用后
1 2 3*4 5*6 7 8*9 10 11*12 13 14*15*16*
int number = Console.readInt(); int[] digits = new int[3]; digits[0] = number % 10;number = number / 10; digits[1] = number % 10;number = number / 10; digits[2] = number % 10;number = number / 10; Console.println(digits[2]);Console.println(digits[1]);Console.println(digits[0]);
效果

一气声明多个数据格

数组声明及创建

标准格式
<数组变量声明> = <数组创建>;
<元素类型>[] <数组变量名> = new <元素类型>[<数组尺寸>];
int[] digits = new int[3];
兼容格式
<元素类型> <数组变量名>[] = new <元素类型>[<数组尺寸>];
int digits[] = new int[3];

默认值

通过 new 创建的数组, 每个数据格里都是该类型的默认值

类型默认值
int0
double0.0
booleanfalse

元素Elements

管数组里的每个变量叫元素

索引Index

数组使用索引定位数据格

格式
1
<数组名>[<索引值>]
样例
1 2 3 4 5
// 赋值digits[2] = number % 10; // 取值Console.println(digits[2]);

索引范围

索引值范围从 0 开始 到 尺寸 - 1

数组越界
1 2!3!
int[] digits = new int[5];System.out.println(digits[5]);System.out.println(digits[-1]);

访问越界的索引会导致运行时报错

强类型数组

数组里的每个元素的类型都是一样的

1!
digits[0] = 3.7;

数组字面量

格式
{<元素字面量1>, <元素字面量2>, ..., <元素字面量n>}
样例
int[] digits = {2, 7, 3, 8, 4}; 

长度不可改

一旦创建时确定了数组的长度, 之后就不能改

如果需要, 只能造一个新的

1 2 3
int[] arr1 = new int[3];...int[] arr2 = new int[5];

一维数组 和 条件语句 的关系

使用前
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
int number = Console.readInt(); String code = "";switch (number) { case 0: code = "-----"; break; case 1: code = ".----"; break; case 2: code = "..---"; break; case 3: code = "...--"; break; case 4: code = "....-"; break; case 5: code = "....."; break; case 6: code = "-...."; break; case 7: code = "--..."; break; case 8: code = "---.."; break; case 9: code = "----."; break;}Console.println(code);
使用后
1*2*3 4 5*6 7
String[] codes = {"-----", ".----", "..---", "...--", "....-", ".....", "-....", "--...", "---..", "----."}; int number = Console.readInt();String code = codes[number]; Console.println(code);
特性

分支结构的判断是一个变量

值是连续的

for 语句for Statements

作用

用于机械式重复一段代码

案例对比

使用前
1 2 3 4
String name = "ZZAX";Console.println(name);Console.println(name);Console.println(name);
使用后
1 2*3 4*
String name = "ZZAX";for (int i = 0; i < 3; i++) { Console.println(name);}

语法

for (<初始化>; <维持条件>; <改变>){
    <statements>
}

维持条件部分 必须为 布尔值表达式

执行顺序

1
for (2; 3; 4){
    5
}
6

1 23 543 543 543 ... 543 6

3 有没有可能不执行 ?
A

一定会执行

B

可能不执行

4 有没有可能不执行 ?
A

一定会执行

B

可能不执行

5 有没有可能不执行 ?
A

一定会执行

B

可能不执行

标准 for 语句

一般
for (int i = 3; i > 1; i--){
    ...
}
标准
for (int i = 0; i < <次数>; i++){
    <statements>
}

唯一可以变的,就是 i 的名字,和 次数。

利用 i 值

1 2 3 < < <
for (int i = 0; i < 3; i++) { Console.println(i);}012

for 语句 编写技巧

案例

输出 9 - 0

1.

先写出不循环的版本

1 2 3 4 5 6 7 8 9
Console.println(9);Console.println(8);Console.println(7);Console.println(6);Console.println(5);Console.println(4);Console.println(3);Console.println(2);Console.println(1);
2.

准备模板

1 2 3
for(int i = 0; i < <次数>; i++) { <statements>}
3.

填次数

1*2 3
for(int i = 0; i < 9; i++) { <statements>}
4.

填相同

相同
1
Console.println(<不同>);
填进去
1 2*3
for(int i = 0; i < 9; i++) { Console.println(<不同>);}
5.

找规律 填公式

数据
v: 9 8 7 6 5 4 3 2 1
i: 0 1 2 3 4 5 6 7 8
规律
v = 9 - i
填进去
1 2+3*4
for(int i = 0; i < 9; i++) { int value = 9 - i; Console.println(value);}

挑战

输出 1 3 5 7 9

for 语句 x 变量作用域

案例

代码
1 2 3 4 5
for(int i = 0; i < 3; i++) { int value = 3 - i; Console.println(value);}Console.println("end");
人工内存
Line                            io
1.1     0                      
1.2     |                       =   true
2       |       3
3       |       |               <   3
4       |       x       
1.3     1       
1.2     |                       =   true
2       |       2
3       |       |               <   2
4       |       x
1.3     2   
1.2     |                       =   true
2       |       1
3       |       |               <   1
4       |       x
1.3     3   
1.2     |                       =   false
4       x
5                               <   end
        i       value

规则

语句头

for 语句头的初始化部分的 变量 在最后一次碰到回 大括号的时候死

循环期间一直保留

语句内

for 语句里的 变量 每次撞到 回大括号 都死一次

每次循环都是新的

注意

在 for 语句里 可以用到的变量有

for 语句外面的

for 语句头里声明的

for 语句里声明的

for 语句 x 数组

使用前
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
int number = Console.readInt(); int[] digits = new int[3]; digits[0] = number % 10;number = number / 10; digits[1] = number % 10;number = number / 10; digits[2] = number % 10;number = number / 10; Console.println(digits[2]);Console.println(digits[1]);Console.println(digits[0]);
使用后
1 2 3 4 5 6 7 8 9 10 11 12
int number = Console.readInt(); int[] digits = new int[3]; for (int i = 0; i < 3; i++) { digits[i] = number % 10; number = number / 10;} for (int i = 0; i < 3; i++) { Console.println(digits[2 - i]);}

循环控制

循环 内嵌 if 语句

可以内嵌 if 语句, 实现循环时达到分支效果

1 2 3 4 5
for (...){ if (...) { }}
挑战

基于下面的代码。写 循环输出

1 2
int[] arr = {6, 7, 3, 8, 4};// todo

使得输出

6, 7, 3, 8, 4

循环 与 boolean 运算 做假设验证

1 2 3 4 5 6
boolean test = false;for (...){ if (...) { test = true; }}
特性

只有每次循环,if 语句条件都不成立时,test 才会是 false

假设一个很难证明的

条件内赋值一个很好推翻的

挑战

检测数组里是否有 0,输出 true 或者 false

break 控制

立刻停止下面语句, 跳出循环

一般内嵌在条件语句里

代码
1
for (2; 3; 4){
    51
    if (52) {
        break;
    }
    53
}
6
执行顺序
1
2 3 
51 52 53 4 3
51 52 break
7

continue 控制

立刻停止下面语句, 尝试下次循环

一般内嵌在条件语句里

代码
1
for (2; 3; 4){
    51
    if (52) {
        continue;
    }
    53
}
6
执行顺序
1
2 3 
51 52 53 4 3
51 52 continue 4 3
51 52 53 4 3
7

早退出Early Exit

输出有几个 不是 0 的数

使用前
1 2 3 4 5 6 7 8
int[] arr = {6, 7, 3, 8, 4};int count = 0;for (int i = 0; i < arr.length; i++) { if (arr[i] != 0) { count++; }}Console.println(count);
使用后
1 2 3 4*5*6 7+8 9
int[] arr = {6, 7, 3, 8, 4};int count = 0;for (int i = 0; i < arr.length; i++) { if (arr[i] == 0) { continue; } count++;}Console.println(count);
效果

使得主逻辑的代码 的缩进 减少1个

字面量规范

使用原值

代码中 如果有 计算出来的字面量, 那么需要写是怎么计算的

使用前
1 2 3 4 5 6 7 8
int[] arr = {6, 7, 3, 8, 4}; for (int i = 0; i < 5; i++) { Console.print(arr[i]); if (i != 4) { Console.print(", "); }}
使用后
1 2 3 4 5*6 7 8
int[] arr = {6, 7, 3, 8, 4}; for (int i = 0; i < 5; i++) { Console.print(arr[i]); if (i != 5 - 1) { Console.print(", "); }}

为业务值定义变量

使用前
1 2 3 4 5 6 7 8
int[] arr = {6, 7, 3, 8, 4}; for (int i = 0; i < 5; i++) { Console.print(arr[i]); if (i != 5 - 1) { Console.print(", "); }}
使用后
1 2+3*4 5*6 7 8
int[] arr = {6, 7, 3, 8, 4};int size = 5;for (int i = 0; i < size; i++) { Console.print(arr[i]); if (i != size - 1) { Console.print(", "); }}

注意

引用变量

任何值 如果能从已知变量中计算出来, 那么就使用 已知变量

使用前
1 2 3 4 5 6 7 8
int[] arr = {6, 7, 3, 8, 4}; for (int i = 0; i < 5; i++) { Console.print(arr[i]); if (i != 5 - 1) { Console.print(", "); }}
使用后
1 2 3*4 5*6 7 8
int[] arr = {6, 7, 3, 8, 4}; for (int i = 0; i < arr.length; i++) { Console.print(arr[i]); if (i != arr.length - 1) { Console.print(", "); }}

最终效果

程序中只能出现 业务数据 和 -1, 0, 1, 2

原始数据值 只能出现一次

while 语句while Statements

案例

随机生成一个 1 - 9 之间的奇数

1 2 3 4 5
int number;do { number = new Random().nextInt(10); Console.println(number);} while (number % 2 == 0);

用途

用于执行不确定次数的重复

while 语法

while (<condition>) {
    <statements>
}

while 执行顺序

1
while (2) {
    3
}
4

1 2 32 32 ... 32 4

3 有没有可能不执行
A

一定会执行

B

可能不执行

do while 语法

do {
    <statements>
} while (<condition);

do while 执行顺序

1
do {
    2
} while (3)
4

1 23 23 ... 23 4

2 有没有可能不执行
A

一定会执行

B

可能不执行

while 循环控制

死循环
1 2 3
while(true) { ...}
跳出循环
1 2 3 4 5 6 7
while(true) { ... if (...) { break; } ...}
其它

while 里 也可以写 continue

while 语句 编写技巧

案例

< < > < < < > < < < > <
查询余额请按 1结束请按 91您的余额为 100 元查询余额请按 1结束请按 91您的余额为 100 元查询余额请按 1结束请按 99再见
1.

原始代码

写出非循环版本

1 2 3 4 5 6 7 8 9 10 11 12
Console.println("查询余额请按 1");Console.println("结束请按 9");Console.readInt();Console.println("您的余额为 100 元");Console.println("查询余额请按 1");Console.println("结束请按 9");Console.readInt();Console.println("您的余额为 100 元");Console.println("查询余额请按 1");Console.println("结束请按 9");Console.readInt();Console.println("再见");
2.

死循环

找到重复单元,套在 死循环里

1*2 3 4 5 6*7
while(true) { Console.println("查询余额请按 1"); Console.println("结束请按 9"); Console.readInt(); Console.println("您的余额为 100 元");}Console.println("再见");
3.

找出口

找到跳出情况,写 if break

1 2 3 4*5+6+7+8 9 10
while(true) { Console.println("查询余额请按 1"); Console.println("结束请按 9"); int option = Console.readInt(); if (option == 9) { break; } Console.println("您的余额为 100 元");}Console.println("再见");
4.

校验

运行,测试次数是否正确

while 语句 死循环 简化 一般 while 语句

规则

如果 if break 在 最后一句,可以转为 do while condition

如果 if break 在 第一句,可以转为 while condition

其它情况,不能简化

注意:转换时,逻辑需要反转

案例
使用前
1 2 3 4 5 6 7 8
Console.println("我说鸡蛋,你说要");while(true) { Console.println("鸡蛋"); String command = Console.readLine(); if (!command.equals("要")) { break; }}
使用后
1 2+3 4 5*6*
Console.println("我说鸡蛋,你说要");Stirng command;do { Console.println("鸡蛋"); command = Console.readLine();} while (command.equals("要"));

注意:判断挪到 while condition 区域时,可能需要提高变量的作用域

循环 语句 对比

whiledo while 的区别

while 先检查,再执行,有可能不执行

do while 先执行,再检查,保障至少执行一次

whilefor 的区别

for 用于 知道 次数的循环 更贴切

while 用于 不知道 次数的循环 更贴切

forwhile 互转

forwhile
1
for(2; 3; 4) {
    5
}
6

可转为

1
2
while(3) {
    5
    4
}
6

前提是里面没有 continue 或者 break

案例分析

输出一个数组里的值,遇到 0 就停,不输出 0

程序会因为 不确定的 0 的出现 而停止

程序也会因为 确定的 元素结束 而停止

for 版本
1 2 3 4 5 6 7 8 9
int[] arr = {6, 7, 0, 8, 4}; for (int i = 0; i < arr.length; i++) { if (arr[i] == 0) { break; } else { Console.println(arr[i]); }}
while 版本
1 2 3 4 5 6 7 8 9 10 11 12 13
int[] arr = {6, 7, 0, 8, 4};int i = 0;while (true) { if (arr[i] == 0) { break; } else { Console.println(arr[i]); i++; if (i == arr.length) { break; } }}
for x 早推出 版本
1 2 3 4 5 6 7 8
int[] arr = {6, 7, 0, 8, 4}; for (int i = 0; i < arr.length; i++) { if (arr[i] == 0) { break; } Console.println(arr[i]);}
while x 早推出 版本
1 2 3 4 5 6 7 8 9 10 11 12
int[] arr = {6, 7, 0, 8, 4};int i = 0;while (true) { if (arr[i] == 0) { break; } Console.println(arr[i]); i++; if (i == arr.length) { break; }}
for x 断义 版本
1 2 3 4 5
int[] arr = {6, 7, 0, 8, 4}; for (int i = 0; i < arr.length && arr[i] != 0; i++) { Console.println(arr[i]);}
while x 断义 版本
1 2 3 4 5 6 7
int[] arr = {6, 7, 0, 8, 4}; int i = 0;while (i < arr.length && arr[i] != 0) { Console.println(arr[i]); i++;}

存储介质

一些练习中,你需要好好考虑,使用什么存储介质(专业名词叫 数据结构)更恰当

整数补 0 循环版

Q2 E02

使用 int 存储输入数据

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
int number = Console.readInt(); // 探测 number 的位数 int digitSize = ... // 计算 前面需要补0 的个数int leadingZeroSize = ... // 打印 前面的 0 for(int i = 0; i < leadingZeroSize; i++) { ...} // 打印 原始数据Console.println(number);

使用 int 数组 存储输入的数据

1 2 3 4 5 6 7 8 9 10 11 12 13 14
int limit = 4;int number = Console.readInt(); // 存入 数组int[] digits = new int[limit];for (int i = 0; i < limit; i++) { int index = limit - i - 1; ...} // 打印 出来for (int i = 0; i < limit; i++) { Console.print(digits[i]);}

ZZAX 微信公众

文档一更新,立刻告诉你