目录
本章学习流程控制结构的第三种:循环结构。
- 顺序结构:从上到下
- 选择结构:根据条件,执行对应的内容
- 循环结构:反复执行
一、概述
1.1 使用循环结构的缘由
之前的问题一:switch结构,根据数字输出对应是星期几的例题?
每次验证不同的数据,都需要重新执行一遍程序
问题二:求1到100的累加和?
1.2 循环结构的分类
(1)while循环
(2)do-while循环
(3)for循环
(4)嵌套的循环
1.3 循环常用的语句
(1)break语句
(2)continue语句
二、while循环
2.1 语法格式
2.2 执行流程
例题:将小于5的整数打印输出?
1.代码如下:
2.具体的执行流程:
循环条件成立,执行循环体;一旦循环条件不成立,结束循环。
n | n<5 | 输出n | n++ |
---|---|---|---|
1 | true | 1 | 2 |
2 | true | 2 | 3 |
3 | true | 3 | 4 |
4 | true | 4 | 5 |
5 | false:结束循环 |
2.3 案例应用1
1.求1到5的累加和?
- 新建一个包:
还是没明白,为什么要域名的反写?
- 代码如下:
package com.imooc.flow1;
public class PlusDemo {
public static void main(String[] args) {
// 求1到5的累加和?1+2+3+4+5
int n=1;
int sum=0; // sum是存放和的变量
while(n<=5) {
sum=sum+n;
n++; // 即:n=n+1
}
System.out.println("1到5的累加和为:"+sum);
}
}
--->
1到5的累加和为:15
- 具体的执行流程:
n | sum | n<=5 | sum=sum+n | n++ |
---|---|---|---|---|
1 | 0 | true | 0+1=1 | 2 |
2 | 1 | true | 1+2=3 | 3 |
3 | 3 | true | 3+3=6 | 4 |
4 | 6 | true | 6+4=10 | 5 |
5 | 10 | true | 10+5=15 | 6 |
6 | 15 | false:循环终止 |
上述是正确的写法。下面演示下错误的写法:
因为上述循环变量一直满足循环t条件,所以是死循环。
2.思考题:上面累加的数之间都是差1,如何求得1+3+5+7+9+11+13+15=?
package com.imooc.flow1;
public class Test1 {
public static void main(String[] args) {
int n=1;
int sum=0; // sum是存放和的变量
while(n<=15) {
sum=sum+n;
n=n+2; // 因为公差是2
}
System.out.println("1到15的等差数列累加和为:"+sum);
}
}
--->
1到15的等差数列累加和为:64
2.4 案例应用2
循环输出26个英文小写字母,并分两行输出?
- 字符型数据的输出
- 控制在两行输出
(1)先不换行的写法:
package com.imooc.flow1;
public class CharDemo {
public static void main(String[] args) {
char ch='a';
int count=1; // 控制换行的变量
while(ch<='z') {
System.out.print(ch+" ");
ch++; // 循环体中没用到count变量啊
}
}
}
--->
a b c d e f g h i j k l m n o p q r s t u v w x y z
(2)换行的写法:
package com.imooc.flow1;
public class CharDemo {
public static void main(String[] args) {
char ch='a';
int count=1; // 控制换行的变量
while(ch<='z') { // 因为字符型与ASCII码一一对应:按照字母表顺序ASCII码逐渐增大
System.out.print(ch+" ");
if(count%13==0) // 当且仅当count是13的整数倍时,才换行
System.out.println();
count++;
ch++;
}
}
}
--->
a b c d e f g h i j k l m
n o p q r s t u v w x y z
2.5 键盘接受多种数据类型的方法总结
代码演示:
比较特殊的是字符型数据,Java中没有专门接受字符型数据的方法。
如果要接受字符型数据,必须先接受字符串类型,然后通过字符串的charAt()方法,获得字符串类型数据的第一个字符。即:
三、do-while循环
3.1 语法格式
先斩后奏嘛
3.2 执行流程
例题:将小于5的整数打印输出?
1.代码如下:
2.具体的执行流程:
先执行循环体,再去判断循环条件;一旦循环条件不成立,结束循环。
n | 输出n | n++ | n<5 |
---|---|---|---|
1 | 1 | 2 | true |
2 | 2 | 3 | true |
3 | 3 | 4 | true |
4 | 4 | 5 | false:终止循环 |
3.3 案例应用1
1.求1到5的累加和?
package com.imooc.flow1;
public class DoWhileDemo {
public static void main(String[] args) {
// 求1到5的累加和?
int n=1;
int sum=0; // 累加时赋值为0,因为0加任何数,相当于没有加
do{
sum=sum+n;
n++;
}while(n<=5);
System.out.println("sum="+sum);
}
}
--->
sum=15
当是累乘时,上面的就应该时int sum=1;
,因为1乘以任何数,相当于没有乘。
3.4 案例应用2
猜字游戏:要求猜测一个介于1到10的之间的数字,然后,将猜测值与实际值进行比较,并给出提示,以便能更接近实际值,直到猜中为止。
1.程序分析:
(1)给定要猜中的原始数字a
(2)使用循环结构
(3)循环条件:只要猜的数字,跟原始数字a不一样,就一直猜下去;一旦猜中,循环结束
(4)循环体:输入要猜的数字,进行判断
(5)输出猜测猜中的值
package com.imooc.flow1;
import java.util.Scanner;
public class GuessDemo {
public static void main(String[] args) {
// 设置猜中的数和要猜的数
int number=6;
int guess; // 存储键盘接受的数字
System.out.println("猜一个介于1到10之间的数字");
do {
System.out.println("请输入您要猜的数:");
Scanner sc=new Scanner(System.in);
guess=sc.nextInt();
if(guess>number) {
System.out.println("太大!");
}else if(guess<number){ // if(){}中间不能有分号!
System.out.println("太小!");
}
}while(guess!=number); // 只要你满足循环条件,就一直循环执行
System.out.println("您猜中了!答案为"+number);
}
}
--->
猜一个介于1到10之间的数字
请输入您要猜的数:
1
太小!
请输入您要猜的数:
8
太大!
请输入您要猜的数:
6
您猜中了!答案为6
2.上述要猜中的数是直接写在程序中,下面演示使用一个随机数作为要猜中的数:
利用方法Math.random()表示[0,1)
的基础特性:
Math.random()-----------[0,1)之间的随机数,包括浮点数和整型
Math.random()*10--------[0,10)之间的随机数,包括浮点数和整型
Math.random()*10+1------[1,11)之间的随机数,包括浮点数和整型
代码如下:
package com.imooc.flow1;
import java.util.Scanner;
public class GuessDemo {
public static void main(String[] args) {
// 设置猜中的数和要猜的数
int number=(int)(Math.random()*10+1); // 将[1,11)之间的随机整数提取为整型,即1~10之间的整数
System.out.println("number="+number);
int guess;
System.out.println("猜一个介于1到10之间的数字");
do {
System.out.println("请输入您要猜的数:");
Scanner sc=new Scanner(System.in);
guess=sc.nextInt();
if(guess>number) {
System.out.println("太大!");
}else if(guess<number){
System.out.println("太小!");
}
}while(guess!=number); // 只要你满足循环条件,就一直循环执行
System.out.println("您猜中了!答案为"+number);
}
}
--->
number=6 // 如果是真实的猜字游戏,这里不该出现谜底、让别人知道。
猜一个介于1到10之间的数字
请输入您要猜的数:
1
太小!
请输入您要猜的数:
7
太大!
请输入您要猜的数:
6
您猜中了!答案为6
四、for循环
4.1 语法格式
1.之前的while循环的语法格式
2.for循环的格式
4.2 案例应用1
使用for循环,求1到5的累加和?
1.代码如下:
package com.imooc.flow1;
public class ForDemo {
public static void main(String[] args) {
int sum=0;
for(int n=1;n<=5;n++) { // int n=1只执行一次,因为原来指代的就是变量的初始化
sum=sum+n;
}
System.out.println("sum="+sum);
}
}
--->
sum=15
2.上述for循环的执行顺序:
4.3 局部变量的作用范围
(主)方法中定义的变量称为局部变量。
变量定义的位置不同,对输出结果有什么影响?
由此可见,局部变量的作用范围,只在定义它的大括号内有效。
4.3 注意事项
for循环中的三个表达式是可以省略的,如果省略会出现什么情况,如何解决?
例题:将10以下的数字打输出
1.for循环,正常的写法:
package com.imooc.flow1;
public class ForDemo1 {
public static void main(String[] args) {
for(int i=1;i<=10;i++)
System.out.print(i+" "); // 注意:循环结束后,i的值是11
}
}
--->
1 2 3 4 5 6 7 8 9 10
2.for循环,省略表达式1和表达式2的写法:
package com.imooc.flow1;
public class ForDemo1 {
public static void main(String[] args) {
int i=1;
for(;;i++) {
System.out.print(i+" ");
if(i==10)break; // 在循环体中补写一条判断语句,来结束循环
}
}
}
--->
1 2 3 4 5 6 7 8 9 10
3.循环输入数字1-10并相应的输出,如果输入0则跳出循环。
五、三种循环结构的应用场景
5.1 while循环
适用于:不知道具体循环次数,但是知道循环达到某个条件时就执行。所以,循环体内会对循环变量进行改变,以避免死循环。
5.2 do-while循环
适用于:同上,不知道具体循环次数,但是知道循环达到某个条件时就执行,并且,循环肯定要执行一次。
5.3 for循环
三个表达式依次执行,执行顺序固定,适用于:循环次数固定的场景。
六、嵌套循环
一个循环内部,还有另外一个循环,叫嵌套循环。即为外重循环+内重循环。
6.1 分类
1.while循环+while循环
2.do-while循环+while循环
3.for 循环+for循环
除了上述三种,for循环也是可以和while循环进行嵌套的。即以上两两皆可嵌套。
6.2 案例应用1
使用嵌套的while循环,以输出4行4列的星号,组成一个正方形?
- 外重循环:控制有多少行
- 内重循环:控制有多少列
1.演示错误的写法
- 代码如下:
package com.imooc.flow1;
public class StarDemo1 {
public static void main(String[] args) {
int m=1; // 外重循环的循环变量
int n=1; // 内重循环的循环变量
System.out.println("输出4行4列的星号");
// 外重循环,控制输出几行
while(m<=4) {
// 内重循环,控制每行输出几个星号
while(n<=4) {
System.out.print("*");
n++;
}
System.out.println(); // 换行
m++;
}
}
}
--->
输出4行4列的星号
****
- 执行流程:
上述出错的原因,就是每执行一次外重循环,内重循环的n永远是5,也就是说,永远不执行内重循环。
2.正确的写法:
- 代码如下:
package com.imooc.flow1;
public class StarDemo1 {
public static void main(String[] args) {
int m=1; // 外重循环的循环变量
int n=1; // 内重循环的循环变量
System.out.println("输出4行4列的星号");
// 外重循环,控制输出几行
while(m<=4) {
// 内重循环,控制每行输出几个星号
n=1; // 对n重新赋值:每次外重循环一开始,那就从1开始增
while(n<=4) {
System.out.print("*");
n++;
}
System.out.println(); // 换行
m++;
}
}
}
--->
输出4行4列的星号
****
****
****
****
- 执行流程:
3.上述运行的是4行4列的正方形,能否改进运行得出直角三角形?
package com.imooc.flow1;
public class StarDemo1 {
public static void main(String[] args) {
int m=1; // 外重循环的循环变量
int n=1; // 内重循环的循环变量
System.out.println("输出4行4列的星号");
// 外重循环,控制输出几行
while(m<=4) {
// 内重循环,控制每行输出几个星号
n=1; // 将n重新置1,每次外重循环一开始,那就从1开始增
while(n<=m) { // 内重循环中的循环变量是变化的
System.out.print("*");
n++;
}
System.out.println(); // 换行
m++;
}
}
}
--->
输出4行4列的星号
*
**
***
****
6.3 案例应用2
求阶乘1!+2!+3!+4!+5!+6!+7!+8!+9!+10!
的累加和?
- 外重循环:加法运算
- 内重循环:阶乘运算
1.演示错误的写法:
package com.imooc.flow1;
public class JiechengPlus {
public static void main(String[] args) {
int s=1,sum=0;
for(int i=1;i<=4;i++) {
for(int j=1;j<=i;j++) {
s=s*j; // s存放阶乘计算的结果
}
sum=sum+s;
}
System.out.println("1!+2!+3!+4!="+sum);
}
}
--->
1!+2!+3!+4!=303 // ❌
2.正确的写法:
package com.imooc.flow1;
public class JiechengPlus {
public static void main(String[] args) {
int s=1,sum=0;
for(int i=1;i<=4;i++) {
s=1; // 将s重新置1,即外重循环每开始一次,s就从1重新计算
for(int j=1;j<=i;j++) {
s=s*j; // s存放阶乘计算的结果
}
sum=sum+s;
}
System.out.println("1!+2!+3!+4!="+sum);
}
}
--->
1!+2!+3!+4!=33
3.当变量的数据类型不够时
将变量的数据类型,由整型int,改为长整型long:
如果长整型long还不能存储时,Java专门提供了处理大数据的类。
七、break语句和continue语句
7.1 break语句
1.用途
在之前的switch结构中,曾经用过:跳出当前的switch结构。
在之前的循环结构中,也曾经使用过:跳出当前的循环。
感觉像是个黑洞blackhole,特殊情况下一旦满足,就跃出你现在的时空
总结其用途:
- 结束当前循环的执行,即循环体中位于break语句后面的语句就不会执行了
- 在特殊的多重循环中,break语句只向外跳一层。也就是说,不影响外重循环。
2.多重循环中的用途
在多重循环中,查看和感受其执行流程:
7.2 continue语句
用途:
- 只能用在循环中
- 结束当前循环的执行,但是要继续执行本级循环中的下一次的循环
1.continue语句在单重循环中的应用
求1+3+5+7+9的累加和?
(1)以前只用for循环:
(2)for循环+使用continue语句
执行流程如下:
2.continue语句在双重循环中的应用
执行流程:
i | j | j%2==0 | k |
---|---|---|---|
1 | 1 | false | 0+1=1 |
1 | 2 | true | |
1 | 3 | false | 1+3=4 |
1 | 4 | true | |
2 | 1 | false | 4+1=5 |
2 | 2 | true | |
2 | 3 | false | 5+3=8 |
2 | 4 | true | |
... | ... | ... | ... |
4 | 3 | false | 13+3=16 |
4 | 4 | true | |
5 | 循环结束 |
本质,还是让某种具体的特殊情况失效
八、调试初步
程序调试,即debug,就是找程序的缺陷、错误。
8.1 起源
大型电脑中夹住了一个小虫子:bug就指代程序的缺陷、错误。
8.2 调试的作用
帮助程序员通过查看变量值的变化,看清程序每一步的效果。
8.3 调试步骤
(1)设置断点
breakpoint.
双击;
右键|Togglebreakpoint
(2)执行调试
右键|debug as
或Run|Debug
调试模式下的窗口的界面:
(3)进行单步调试
单步调试即step over,其快捷键:F6
转换视图:
8.4 多断点调试
断点之间的调试:F8
断点如果设置在for循环的内部:
九、总结
十、关于课后作业的思考:
昨天想了好久、试了好久,就是不知道问题出在哪里:
今天早上再看,细细梳理了一遍执行流程,恍然大悟:
其实,问题出在第一个二重循环,j永远都是从4到1,最后永远是一个4空格。其实应该是递减的。
那么,j的最大值就得变化:
OK~
Comments | NOTHING