4,循环结构
4.1,循环结构语句
它可以在满足条件的情况下,反复执行某一段代码。 这段被重复执行的代码称为循环体语句。 当反复执行循环体的时候,需要在合适的时候把循环的判断条件变为false,从而来结束循环,否则循环会一至执行下去,成为了死循环。
4.2,循环结构语句的组成
- 初始化语句:
一条或者多条语句,完成一些初始化的操作 - 判断条件语句:
是一个boolean类型表达式,决定循环体是否继续执行 - 循环体语句:
就是我们要多次执行的代码 - 控制条件语句
这个语句在每一次循环结束后,下一次循环判断条件执行前执行。
用于控制循环条件中的变量,可以让循环在合适的时候结束
4.3,分类
- for循环
- while循环
- do…while循环
4.3.1,for循环
- 格式:
1 2 3
for(初始化语句;判断条件语句;控制条件语句){
4
循环体语句;
}
1243243243243…直到条件为假循环结束 - 执行流程
a:执行初始化语句
b:执行判断条件语句,看结果是真还是假
如果是false,循环结束
如果是true,继续执行
c:循环体语句
d: 执行控制条件语句
e: 回到b步骤继续执行 - 看图
//需求:我要在控制台上输出10次 我爱你
//我要输出1000次? 100000次?
//目前这种方式很明显不合适
class Demo3{
public static void main(String[] args){
System.out.println("我爱你");
System.out.println("我爱你");
System.out.println("我爱你");
System.out.println("我爱你");
System.out.println("我爱你");
System.out.println("我爱你");
System.out.println("我爱你");
System.out.println("我爱你");
System.out.println("我爱你");
System.out.println("我爱你");
//上面是原始做法,明显不好。
//我们可以使用循环结构改进代码
System.out.println("--------------------------");
for(int i=1;i<=100;i++){
System.out.println("我爱你");
}
}
}
- 注意事项:
判断条件语句不管是简单还是复杂结果必须是boolean类型。循环体语句如果是一条语句,大括号可以省,如果是多条语句,绝对不能省,建议永远不要省。
//我要在控制台上输出1到10这几个数字
class Demo4{
public static void main(String[] args){
//原始做法
System.out.println("1");
System.out.println("2");
System.out.println("3");
System.out.println("4");
System.out.println("5");
System.out.println("6");
System.out.println("7");
System.out.println("8");
System.out.println("9");
System.out.println("10");
System.out.println("-------------------");
//应该用循环来写
for(int i=1;i<=10;i++){
System.out.println(i);
}
System.out.println("-------------------");
//应该用循环来写
for(int i=0;i<10;i++){
System.out.println(i+1);
}
}
}
//求1到10的数据之和
/*
分析:
首先需要2个变量:
一个变量用来存储第一个加数,第一个加数其实保存的是之前的所有数据和。默认值应该是0
一个变量用来存储第二个加数,第二个加数其实是每次的数据变化的值
*/
class Demo5{
public static void main(String[] args){
//原始做法:
//System.out.println(1+2+3+4+5+6+7+8+9+10);
//定义第一个加数
int sum = 0;
//依次获取1到10这几个数字
for(int i=1;i<=10;i++){
//这个i就是第二个加数
//sum = sum + i;
sum += i;
/*
0 +1 = 1
1+2 = 3
3+3 = 6
....
*/
//System.out.println("sum="+sum);
}
System.out.println("sum="+sum);
}
}
/*
求1到100之间的奇数和
求1到100之间的偶数和
*/
class Demo6{
public static void main(String[] args){
int sum1 = 0;//累加偶数和
int sum2 = 0;//累加奇数和
//for循环可以获取1到100之间的每一个数字
for(int i=1;i<=100;i++){
//System.out.println("i="+i);
//sum += i;
//判断i是否是偶数
if(i%2 == 0){
sum1 += i;
}else{
sum2 += i;
}
}
System.out.println("1-100之间的所有偶数和:"+sum1);
System.out.println("1-100之间的所有奇数和:"+sum2);
System.out.println("----------------------------------");
//另一种做法 求偶数和
int sum3 = 0;
for(int i=0;i<=100;i+=2){
sum3 += i;
}
System.out.println("1-100之间的所有偶数和:"+sum3);
//求奇数和自己写一下
}
}
- 练习:求10的阶乘(可以加上键盘输入)
//求键盘输入数的阶乘(b)
int a = 1;
Scanner sc = new Scanner(System.in);
int b = sc.nextInt();
for(int i = 1; i <= b ; i++){
a *= i;
}
System.out.println(b+"的阶乘为"+a);
/*
在控制台上输出所有的水仙花数
水仙花数?
是一个三位数
各个位上的数字的立方和等于该数本身
153就是一个水仙花数
1*1*1+5*5*5+3*3*3 = 1+ 125 +27 = 153
分析:
三位数就是告诉了我们范围
通过for循环我们就可以获取每一个三位数
麻烦的是如何获取这个三位数的个位十位和百位
如何获取这个三位数的个位十位和百位?
假设我们现在获取到了一个三位数 153
个位:153%10 = 3
十位:153/10%10 = 5
百位:153/10/10%10 = 1
千位:x/10/10/10%10
万位:.。。。。。
让个位*个位*个位+十位*十位*十位+百位*百位*百位 == 这个数据本身
输出
*/
class Demo7{
public static void main(String[] args){
//三位数告诉我们范围
for(int i=100;i<1000;i++){
int ge = i%10;
int shi = i/10%10;
int bai = i/10/10%10;
//让个位*个位*个位+十位*十位*十位+百位*百位*百位 == 这个数据本身
if((ge*ge*ge+shi*shi*shi+bai*bai*bai) == i){
//输出
System.out.println(i);
}
}
}
}
- 练习:统计水仙花数的个数
//统计水仙花个数(j)
class GeShu{
public static void main(String[] args){
int j = 0;
for(int i = 100; i < 1000;i++){
int ge = i % 10;
int shi = i / 10 %10;
int bai = i / 100 %10;
if((ge*ge*ge + shi*shi*shi + bai*bai*bai) == i){
System.out.println(i);
j++;
}
}
System.out.println(j);
}
- 练习:请输出并统计满足如下条件的数据
条件:这个数据是1-1000之间的数字
要同时满足:
对3整数余2
对5整数余3
对7整除余2
class Test{
public static void main(String[] args){
for(int i = 1; i <= 1000; i++){
if(i%3==2 && i%5==3 && i%7==2){
System.out.println(i);
}
}
}
- 练习:在控制台上输出满足如下条件的五位数
条件:
个位=万位
十位=千位
个位+十位+千位+万位=百位
class Test{
public static void main(String[] args){
for(int i = 1; i < 100000; i++){
int ge = i%10;
int shi = i/10 %10;
int bai = i/100 %10;
int qian = i/1000 %10;
int wan = i/10000 %10;
if(ge == wan && shi == qian && ge+shi+qian+wan==bai){
System.out.println(i);
}
}
}
4.3.2,while循环
-
格式:
初始化语句;
while(判断条件语句){
循环体语句;
控制条件语句;
} -
执行流程:(和for一样)
先走初始化语句
走判断条件语句看是真还是假
假:循环结束
真:走循环体语句
控制条件语句,然后回到判断条件语句
。。。。。
-看图
-
练习:把for循环的所有代码用while写一遍
class Test{
public static void main(String[] args){
/*
//输出十次我爱你
int i = 1;
while(i<=10){
System.out.println("我爱你");
i++;
}
*/
//------------------------------------------
//输出1-10
/*
int i = 1;
while(i<=10){
System.out.println(i);
i++;
}
*/
//------------------------------------------
//求和1-10
/*
int i = 1;
int sum = 0;
while(i<=10){
sum += i;
i++;
}
System.out.println(sum);
*/
//------------------------------------------
//求1-100偶数和、奇数和
/*
int i = 1;
int sum1 = 0;
int sum2 = 0;
while(i<=100){
if(i%2==0){
sum1 += i;
i++;
}
else{
sum2 +=i;
i++;
}
}
System.out.println("偶数和:"+sum1);
System.out.println("奇数和:"+sum2);
*/
//------------------------------------------
//求键盘输入数的阶乘
/*
Scanner sc = new Scanner(System.in);
System.out.println("请输入一个数字:");
int b = sc.nextInt();//键盘输入
int jieCheng = 1;
int i = 1;
while(i<b){
jieCheng *= i;
i++;
}
System.out.println(b+"的阶乘为:"+jieCheng);
*/
//------------------------------------------
//水仙花数
int count = 0;//水仙花数个数
int i = 100;
while(i<1000){
int ge = i%10;
int shi = i/10 %10;
int bai = i/100 %10;
if(ge*ge*ge + shi*shi*shi + bai*bai*bai == i){
System.out.println(i);
count++;
}
i++;
}
System.out.println("水仙花数有"+count+"个");
}
4.3.3,for和while的区别
- 虽然for和while可以等价转换,但是还有有些区别的
- 使用区别:
控制条件语句控制的那个变量
在for循环结束后,就不能被访问了。
而whiel循环结束后,那个变量依然可以被访问
如果在循环结束后还想使用那个变量就用while,否则用for
因为for循环结束后那个变量就从内存消失了,可以提高内存了利用率 - 场景区别:
for循环适合针对一个范围进行判断
while循环适合判断次数不明确的操作
/*
*/
class Demo9{
public static void main(String[] args){
//for格式
for(int i=0;i<10;i++){
System.out.println("默默是帅哥");
System.out.println(i);
}
//System.out.println(i);: 错误: 找不到符号
System.out.println("------------------------");
//while格式
int j = 0;
while(j<10){
System.out.println("默默是大帅哥");
j++;
System.out.println(j);
}
//可以继续访问
System.out.println(j);
}
}
/
*
珠穆朗玛峰的高度是:8848m,假设我有一张足够大的纸,厚度是0.01m
问,我要折叠多少次,才可以保证纸的厚度不低于珠穆朗玛峰的高度
分析:
定义一个统计变量,来记录折叠次数 默认值 0
珠穆朗玛峰的高度是:8848m 这是最终的厚度
假设我有一张足够大的纸,厚度是0.01m 这是起始厚度
问,我要折叠多少次?厚度才能超过8848
每折一次的变化?厚度是之前的2倍
只要每次变化的厚度没有超过8848就继续折,每折一次统计变量++
当超过了8848就结束,最后输出统计变量即可
*/
class Demo10{
public static void main(String[] args){
//定义统计变量
int count = 0;
//为了方便计算把最终厚度和起始厚度同时扩大100倍
//最终厚度
//int end = 8848;
int end = 884800;
//起始厚度
//int start = 0.01;
int start = 1;
//只要纸的厚度超过8848就停止
while(start<end){
//只要厚度没有超过8848,就需要折一次,统计变量就++
count++;
//每折一次的厚度变化
start *= 2;
//可以在这里添加输出语句,把每次叠完之后的结果输出一下
System.out.println("第"+count+"次的厚度是:"+start);
}
//输出统计变量
System.out.println("一共叠了"+count+"次");
}
}
4.3.4,do…while循环
- 格式:
初始化语句;
do{
循环体语句;
控制条件语句;
}while(判断条件语句); - 执行流程:
初始化语句
循环体语句;
控制条件语句
判断条件语句,看结果是真还是假
假:循环结束
真:走循环体语句
回到控制条件语句
继续走判断条件语句,看结果是真还是假
…
-看图
/*
输出10次 龙哥
*/
class Demo11{
public static void main(String[] args){
int i = 0;
do{
System.out.println("龙哥");
i++;
}while(i<10);
System.out.println("--------------------");
//求1-10之和
int sum = 0;
int a = 1;
do{
sum += a;
a++;
}while(a<=10);
System.out.println("sum="+sum);
}
}
- 练习:把前面的练习用do…while写一遍
4.4 循环语句的区别
- do…while循环至少会执行一次循环体语句(先走了一次循环体,然后才判断的)
- 而for和while循环先判断条件是否成立,然后再决定是否要执行循环体。
- 使用的时候,优先考虑for 其次是 while 最后才是do…while
***不管条件是否成立都至少要执行一次循环,这种时候才使用do…while
class Demo12{
public static void main(String[] args){
int i = 5;
while(i<5){
System.out.println("我爱龙哥。");
i++;
}
System.out.println("------------------------");
int j = 5;
do{
System.out.println("我爱默默。");
j++;
}while(j<5);
}
}
4.5,注意事项:
- 注意死循环。。。。。。。
一定要注意控制条件语句控制的那个变量,不要丢了,否则就容易死循环。 - 2种最简单的死循环格式
while(true){
...
}
for(;;){...}
class Demo13{
public static void main(String[] args){
/*
while(true){
System.out.println("啦啦啦");
}
*/
/*
for(;;){
System.out.println("啦啦啦....");
}
*/
int i = 0;
while(i<10){
System.out.println(i);
i++; //这个千万不要忘
}
}
}
5,循环嵌套
5.1,循环嵌套:
就是循环语句的循环体本身又是一个循环语句
- 通过下面案例
外循环控制的是行
内循环控制的是列
/*
需求:我要在控制台上输出如下图形
3行5列的星星图
*****
*****
*****
5行10列
100行1000列
.......
*/
class Demo14{
public static void main(String[] args){
System.out.println("*****");
System.out.println("*****");
System.out.println("*****");
//虽然这个完成了需求,但是不好
//随着我的需求不断的改变,这种方式就适应不了了。
//所以需要改进
//怎么改?
//先要考虑如何打印一行的 * 的问题
//System.out.println("*****"); 不是这个意思,它不能满足变化的需求
//如何打印一个*
//System.out.println("*");
System.out.println("--------------------");
//System.out.println("*");
//System.out.println("*");
//System.out.println("*");
//System.out.println("*");
//System.out.println("*");
//现在可以打印一个*,但是却换行了,我想在一行上怎么办?
//简单System.out.print("*"); 把println的ln去掉 ln实际上就是换行的意思
//System.out.print("*");
//System.out.print("*");
//System.out.print("*");
//System.out.print("*");
//System.out.print("*");
//如果要在一行上打印多个* 这样写比较烦了,代码是重复的。所以可以使用循环来改进
//打印一个4行10列的*图
//打印第一行
/*
for(int i=0;i<10;i++){
System.out.print("*");
}
System.out.println();//可以实现换行
//打印第二行
for(int i=0;i<10;i++){
System.out.print("*");
}
System.out.println();
//打印第三行
for(int i=0;i<10;i++){
System.out.print("*");
}
System.out.println();
//打印第四行
for(int i=0;i<10;i++){
System.out.print("*");
}
System.out.println();
/*
现在同样的代码又重复出现了,说明写的不好,重复出现的代码应该用循环来改进
*/
for(int j=0;j<4;j++){
for(int i=0;i<10;i++){
System.out.print("*");
}
System.out.println();
}
}
}