黑马程序员_毕向东_Java基础_DAY03_循环控制_学习笔记

时间:2021-11-21 12:23:02

----------- android培训java培训、期待与您交流! ------------


/* 黑马程序员_毕向东_Java基础视频教程——

0301-语句(while).avi
0302-语句(do while).avi
0303-语句(for).avi
0304-语句(for和while的区别).avi
0305-语句(循环语句的其他特点).avi
0306-语句(for语句练习-累加&计数器).avi
0307-语句(for嵌套).avi
0308-语句(for嵌套练习).avi
0309-语句(for嵌套-九九乘法表).avi
0310-语句(break-continue).avi
0311-语句(练习).avi

这是DAY03学习中的循环控制部分,后面函数部分后面再发
 */

循环控制


循环控制与条件分支同属流程控制,用于控制程序执行的流程。

【while循环】


while(boolean-exp){
statements
}

while循环被称为“当”型循环,即当条件表达式为true时则重复执行循环体,当条件为false时结束循环。
while循环相当于重复执行N次的if语句。
while循环在第一次即会判断循环条件,如果上来就false,则循环体中的语句可以一次都不会执行。
while循环的循环体中可以仅包含一条空语句。如:
while(true);
while(true){}

条件表达式不仅仅能为boolean常量、变量、表达式,还可以为返回值为boolean的方法调用(比如equals方法),方法内部可以执行任意多的语句。条件表达式不能为空。

循环结构中要含有会改变条件表达式值的语句,不然则为死循环。

循环条件控制变化语句不仅仅可以在循环体中,也可以包含在条件中,如:

int i = 0;
while(i++ < 10){
statements
}//循环了10次

这种结构类似于for(int i = 0; i < 10; i++){statements},但是要注意的是,在循环体中i的使用上不同,while是1~10,for是0~9。

当然,如果把i++放到循环体语句结尾,就跟for一样了。


【do while循环】


类似于直到型循环,执行循环体,直到循环条件为假,结束循环过程。

do{
statement;
}while(boolean-exp);   //注意结尾有分号

do while与while的最大区别在于,do while循环中的语句至少会执行一次。


【for循环】


for(initialzation; boolean-expression; step){

statement
}

for循环是最经常使用的迭代形式,算是一种特殊的当型循环。
执行流程:
1.初始化
2.条件判断,为真继续执行3、为假退出循环结构
3.执行语句
4.步进
5.跳回第2步..

事实上,for循环中的初始化语句、布尔表达式、步进控制、循环体统统都可以为空。如:
for(;;);     //ok:最简单的for语句,无限空循环

当然,既然允许全部为空,亦允许部分为空。

在for循环的初始化和步进控制部分,可以使用一系列由逗号分隔的语句,称为逗号表达式,被分隔的语句均会独立执行。

例:
for(int i = 1, j = 10; i <= 10; i++, j *= i)
System.out.println("i = " + i + ", j = " + j);

需要注意的是,在初始化部分中,可以定义无限多的同类型变量,但是不能定义不同种变量。
定义的类型也不仅限于int,如:

for(int i;;);                                //ok:可以仅声明不初始化
for(int a,b,c,d,e;;);                        //ok:可以声明多个同类变量
for(int a=1,b=2,c=3;;);                      //ok:声明多个同类变量并初始化
//!for(int a,double d;;);                    //error:不能定义不同种变量
for(String s = new String("");;);            //ok:可以声明任何类型的变量
for(String s = new Object().toString();;);   //ok:可以调用方法用来初始化变量

对于循环控制的三个部分,循环条件判断部分要么为空,要么为boolean值,其他两部分可以任意,不一定非要固定为初始
化和步进控制,如:

for(System.out.println("1");System.out.println("2");System.out.println("3"));//error:循环条件不为boolean
for(System.out.println("1");;System.out.println("3"));//ok:前后两部分可以为其他表达式

另外还要注意变量的作用域问题,for语句中定义的变量只在for结构体中有效,循环结束后即被垃圾回收器回收。

int i = 0;
for(int i = 1;;);   //error:重复命名的变量,for语句包含在外围方法体内,外围局部变量在for语句中起作用。

【for循环 or while循环?】


for循环与while循环是可以互换的,用for循环能实现的功能用while循环往往也能实现,反之亦然。

for循环比较适用于明确循环次数的情况。
while循环比较适用于不明确循环次数、需要特殊条件结束循环的情况。

for循环的循环控制变量是局部变量,循环结束后自动释放。而while循环则需要提前定义。这也是二者使用上的一个区分点:

当循环控制变量仅仅起到控制作用、用完就是累赘的时候,用for。当用完后还有其他作用的时候,用while。


【编程解决问题的思路方法】:


拿到一个问题,首先先对问题进行分析,抓住问题关键点。思考人脑分析解决这个问题的分析、解决的思路与步骤。然后
考虑如何用计算机语言来完成这个步骤。考虑复杂问题时可以先将问题进行分解、简化,一步步的理清问题、解决问题。

两种编程思想:计数器思想、累加思想

计数器思想:使用变量对循环中需要计数的事件的发生进行记录,每发生一次自加或自减1。
累加思想:使用变量对需要添加的内容进行记录,通过循环向累加器中不断添加新内容。


【for循环嵌套练习】:


1~10整数和、方块、正倒直角三角、正倒等腰三角、菱形、镂空菱形、组合菱形、心形、九九乘法表等


//这个程序用于测试一些简单的循环应用
public class ForTest{
public static void main(String[] args){

/*//用for循环计算1~10的整数的和
int j = 0;
for(int i = 1; i <= 10; j += i++);
System.out.println("1到10的和为" + j);
*/

/*//用while循环计算1~10的整数的和
int i = 0,j = 0;
while(j < 10){
i += ++j;
}
System.out.println("1到10的和为" + i);
*/

/*
//1~100之间7的倍数有多少个?
int sum = 1;
while(sum * 7 <= 100){
sum++;
}
System.out.println("1~100之间7的倍数有" + (sum - 1) +"个");
*/

/*
//打印正直角三角
for(int i = 1; i <=5; i++){
for(int j = 1; j <= i; j++){
System.out.print("*");
}
System.out.println();
}
*/

/*
//打印倒三角三角
for(int i = 1; i <=5; i++){
for(int j = i; j <= 5; j++){
System.out.print("*");
}
System.out.println();
}
*/

/*//打印正等腰三角
for(int i = 0; i < 4; i++){
for(int j = -4; j <= 4; j++){
System.out.print(Math.abs(j) <= i ? '*' : ' ');
}
System.out.println();
}
*/
/*//打印实心菱形
for(int i = -4; i <= 4; i++){
for(int j = -4; j <= 4; j++){
System.out.print(Math.abs(j) + Math.abs(i) <= 4 ? '*' : ' ');
}
System.out.println();
}
*/

/*//打印空心菱形
for(int i = -4; i <= 4; i++){
for(int j = -4; j <= 4; j++){
System.out.print(Math.abs(j) + Math.abs(i) == 4 ? '*' : ' ');
}
System.out.println();
}
*/
/*//一层循环一条print打印空心菱形
for(int i = -4,j = -4; i <= 4; j++){
System.out.print(Math.abs(i) + j == 5 && (j = -5) != i++ ? "\n" : Math.abs(j) + Math.abs(i) == 4 ? '*' : ' ');
}
*/

/*//打印九九乘法表
for(int i = 1; i <= 9; i++){
for(int j = 1; j <= i; j++){
System.out.print(j + "*" + i + "=" + i * j + "\t");
}
System.out.println();
}
*/
//一层循环一条print打印九九乘法表
for(int i = 1, j = 1; j <= 9; i++){
System.out.print(i + "*" + j + "=" + i * j + (i == j && (i = 0) != j++ ? "\n" : "\t"));
}
}
}


//很久之前写的一个打印大型组合菱形图的代码,贴吧一个兄弟出的题目。
//因为题目追求的是用得语句尽量少,所以代码可读性差些,运行效率也不高。
//思路是将复杂问题分解处理,拆成多层循环,把整体图形拆解为几个大块,大块拆小块,将各部分模块化
//为了让print语句尽量少,通过条件表达式来判断是输出" "还是"*"
//还是基于多层迭代的,没有体现出递归思想
//没有把\n的一句合并到" "、"*"判别中
//没有简化循环嵌套数量,怕简化后让代码变得更加恶心难懂,现在已经够恶心的了

/* OutPut:
*
***
*****
***
*
* * *
*** *** ***
***************
*** *** ***
* * *
* * * * *
*** *** *** *** ***
*************************
*** *** *** *** ***
* * * * *
* * *
*** *** ***
***************
*** *** ***
* * *
*
***
*****
***
*
* * *
*** *** ***
***** ***** *****
*** *** ***
* * *
* * * * * * * * *
*** *** *** *** *** *** *** *** ***
*************** *************** ***************
*** *** *** *** *** *** *** *** ***
* * * * * * * * *
* * * * * * * * * * * * * * *
*** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
***************************************************************************
*** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
* * * * * * * * * * * * * * *
* * * * * * * * *
*** *** *** *** *** *** *** *** ***
*************** *************** ***************
*** *** *** *** *** *** *** *** ***
* * * * * * * * *
* * *
*** *** ***
***** ***** *****
*** *** ***
* * *
*
***
*****
***
*
* * *
*** *** ***
***************
*** *** ***
* * *
* * * * *
*** *** *** *** ***
*************************
*** *** *** *** ***
* * * * *
* * *
*** *** ***
***************
*** *** ***
* * *
*
***
*****
***
*
*/

public class Shape {
/* :用于整理思路的,这个输出的是小菱形模块
public static void printSmallShape(boolean isDiamond){
for(int x = -2; x <= 2; x++){
for(int y = -2; y <= 2; y++){
System.out.print(isDiamond ? Math.abs(x) + Math.abs(y) > 2 ? " " : "*" : " ");
}
System.out.println();
}
}
*/

/* :用来整理思路的,这个输出的是中菱形模块
public static void printMiddleShape(){
for(int a = -2; a <= 2; a++){
for(int x = -2; x <= 2; x++){
for(int b = -2; b <= 2; b++){
for(int y = -2; y <= 2; y++){
System.out.print((Math.abs(a) + Math.abs(b) > 2) ? " " : ((Math.abs(x) + Math.abs(y) > 2) ? " " : "*"));
}
}
System.out.println();
}
}
}
*/

//最终代码,用来输出最终的组合菱形
public static void printBigShape(){
for(int m = -1; m <= 1; m++){
for(int a = -2; a <= 2; a++){
for(int x = -2; x <= 2; x++){
for(int n = -1; n <=1; n++){
for(int b = -2; b <= 2; b++){
for(int y = -2; y <= 2; y++){
System.out.print((Math.abs(m) + Math.abs(n) > 1) ? " " : (Math.abs(a) + Math.abs(b) > 2) ? " " : ((Math.abs(x) + Math.abs(y) > 2) ? " " : "*"));
}
}
}
System.out.println();
}
}
}
}

//将测试模块设置成了静态内部类,将测试部分和主代码分离开来,使用java Shape$ShapeTest来进行测试
public static class ShapeTest{
public static void main(String[] args){
printBigShape();
}
}
}


//一个用于输出可变大小的正倒直角三角、心形的练习程序,本来想实现输出可变大小的心型来着,琢磨半天没实现=。=
//心形想画得好看,规律太难找了,懒得搞了=。=写得很二,分块输出,就当练手了

/*Output:

****** ******
********** **********
************* *************
*****************************
*****************************
*****************************
***************************
***********************
*******************
***************
***********
*******
***
*
*/

public class PrintHeart{

/*
//输出可变大小的正直角三角
public static void printTriangle(int height, int indent, char aChar){
for(int i = 0; i < height; i++){
for(int j = 0; j < (1 + indent * i); j++){
System.out.print(aChar);
}
System.out.println();
}
}
*/

/*//输出可变大小的倒直角三角
public static void printTurnTriangle(int width, int height, int indent, char aChar){
for(int i = 0; i < height; i++){
for(int j = 0; j < (width - indent * j); j++){
System.out.print(aChar);
}
System.out.println();
}
}
*/

//输出心形
public static void printHeart(){
//输出上面的两个MM
for(int i = 0; i < 3; i++){
printBlank(5 - i * 2);
if(i == 0){
printStar(7 - 1);
printBlank(5 + 2);
printStar(7 - 1);
}else{
printStar(7 + i * 3);
printBlank(5 - i * 2);
printStar(7 + i * 3);
}
System.out.println();
}
//输出中间矩形
for(int i = 0; i < 3; i++){
printStar(29);
System.out.println();
}
//输出下部倒三角
for(int i = 0; i < 8; i++){
if(i == 7){
printBlank(i * 2);
printStar(1);
}else{
printBlank(1 + i * 2);
printStar(27 - i * 4);
}
System.out.println();
}
}

//输出连续n个星号
private static void printStar(int n){
for(int i = 0; i < n; i++){
System.out.print("*");
}
}

//输出连续n个空格
private static void printBlank(int n){
for(int i = 0; i < n; i++){
System.out.print(" ");
}
}

//测试单元,分离成静态内部类
public static class PrintHeartTest{
public static void main(String[] args){
printHeart();
}
}
}


【无条件流程控制:return、break、continue】


return应用于方法中:它指定了方法返回的值,促使当前方法退出,并返回那个值。

break应用于循环语句和switch语句中,作用是结束当前结构体。

continue只能应用于循环语句中,作用是结束本次循环,进行下次循环条件判定。

在循环结构中(通常是多重嵌套循环),break与continue可以与标签一起使用,来标示跳转的位置。
标签使用标签名加上一个冒号的形式,如 "label_1:"。


一个示例:

//测试标签与break、coninue的使用

public class LabelTest{
public static void main(String[] args){
int i = 0;
outer:
for(;;){
System.out.println("outer : i = " + i);
inner:
for(;;i++){
System.out.println("inner : i = " + i);
if(i == 3){
System.out.println("continue inner");
continue inner;//等于continue
}
if(i == 5){
System.out.println("continue outer");
i++;//continue outer会直接跳到外侧,跳过自增过程
continue outer;
}
if(i == 8){
System.out.println("break inner");
i++;
break inner;//等于break,也会跳过递增
}
if(i == 10){
System.out.println("break outer");
break outer;//结束循环
}
}
}
}
}/* Output:
outer : i = 0
inner : i = 0
inner : i = 1
inner : i = 2
inner : i = 3
continue inner
inner : i = 4
inner : i = 5
continue outer
outer : i = 6
inner : i = 6
inner : i = 7
inner : i = 8
break inner
outer : i = 9
inner : i = 9
inner : i = 10
break outer
*///:~



----------- android培训java培训、期待与您交流! ------------