【Java编程】程序结构--循环1(while...和do...while)

目录

问题1:自动售票机如何能不断投币和出票?

while 语法结构

问题2:程序读入一个整数,然后输出这个整数是几位数(三位数逆序题)

思路

调试

验证

完整代码

问题3:计数循环(100开始倒数至0,打印“发射”)

问题4:算平均数

小问题

问题5:猜数游戏

思路

问题6:整数分解

思路


顺序结构的程序语句只能被执行一次。如果想要同样的操作执行多次,就需要使用循环结构。Java中有三种主要的循环结构:

  • while 循环
  • do…while 循环
  • for 循环

下面列举了循环的几个例子,重点看【例2】【例4】,涉及到培养一些编程的基础素养。

下面列举了循环的几个例子,重点看【例2】【例4】,涉及到培养一些编程的基础素养。

下面列举了循环的几个例子,重点看【例2】【例4】,涉及到培养一些编程的基础素养。

问题1:自动售票机如何能不断投币和出票?

史博:【Java编程】程序结构--分支icon-default.png?t=N4P3https://zhuanlan.zhihu.com/p/623603391

当投入的金额不够时,乘客继续投票,直到够10元(余额 + 投入金额 >10)售票机出票、找零。

Scanner in = new Scanner(System.in);
                int balance = 0;

        while(true)
        {
                System.out.print("请投币:");
                int amount = in.nextInt();
                balance = amount + balance;     // 余额 = 金额 + 余额

                if (balance >= 10)
                {
                        System.out.println("打印车票");
                        System.out.println("找零:" + (balance-10));
                        balance = 0;            //balance 需要清零
                }
        }

上面的代码,注意出票完成后balance需要清零 balance = 0。

while语句是一个循环语句,它会首先判断一个条件是否满足,如果条件满足,则执行后面紧跟着的语句括号,然

后再次判断条件是否满足,如果条件满足则再次执行,直到条件不满足为止。

while 语法结构

循环变量初始化;
while(循环条件)
{
   循环主体程序;
   循环变量更新规则;   // 循环体内,要有改变条件的机会;
}                    // for 每次变化完,循环变量每次自动更新,更新规则写在for语句里
 
int i = 1;
while(i<=10)
{    
   printf("%d\n",i); // %d是替换整型输出的占位符,\n是回车字符
   i=i+1
}

问题2:程序读入一个整数,然后输出这个整数是几位数(三位数逆序题)

例如: 输入3546, 输出4
输入-2147483647(2的31次方减1),输出10

思路

正常人数,从右往左,个、十、百、千,“1” 后面0个0、1个0、2个0、3个0(位数对应1、2、3、4)。

对于一个数字,先找到它可以被“1后面几个0”除,而这“几个”说的就是"10的几次方",也就是"被10除几次"

的概念。如果可以被n个10除,就用计数器count记n次,这个n的基础上加1,就是位数。

/* 一个数可以被10除1次用if,要不断往下循环,才能看出最后被除了几次,if改成while;
循环条件是true,循环体会被一直执行,停不下来,所以需要增加一个循环条件 while(num>0);*/

Scanner in = new Scanner(System.in);
int num = in.nextInt();
int count = 0;

while (num >0)
{
        num = num / 10;
        count = count + 1;  //计数器
}

调试

程序写好后,需要进行调试(Command +5),在程序适当的地方插入输出来显示变量内容。

验证

常使用边界数据,如有效范围两端的数据、特殊的倍数等:个位数、10、0、负数。

可以查漏:读入的是负数或者0时,也需要被考虑。所以用if...else if...else处理多分支的情况。用数学Math.abs()

绝对值函数可以将正、负数的情况合并,那么上面的程序结构可以简化为两个分支,用if...else即可。

完整代码

                Scanner in = new Scanner(System.in);
                int num = in.nextInt();
                int count = 0;

                if(num != 0)
                {
                        while (num > 0 || num < 0)      // num > 0 || num < 0 与 !=0(非零)等价
                        {
                                num = Math.abs(num) / 10;   //正、负数一并考虑Math.abs()
                                count = count + 1;
                        }
                System.out.println("这是" + count + "位数");    // 等于零的情况
                }
                else
                {
                        System.out.println("0是1位数");    // 等于零的情况
                }

另外,关于算整型数字的位数问题,可以将数字转化为文本,然后.length()的方法。

                Scanner in =new Scanner(System.in);
		int num = in.nextInt();
		System.out.println((num+"").length());

此外,如果输入超出int(2的31次方减1)范围的数字,就会报错。改成long也是。留言区欢迎指点怎么修改~

最后,while是循环执行之前判断是否继续循环,所以有可能循环一次也没有被执行。这时就要看do...while了。

do-while循环和while循环很像,唯一的区别是我们在循环体执行结束的时候才来判断条件。也就是说,无论如

何,循环都会执行至少一遍,然后再来判断条件。

循环变量初始化;
do{
     循环主体程序;
     循环变量更新规则;
  } while(循环条件);

do...while...与while...

如果上面的问题,用do...while代码如下:

Scanner in = new Scanner(System.in);
int num = in.nextInt();
int count = 0;

do
{
 num = Math.abs(num) / 10;
 count = count + 1;
} while (num != 0);      //while后面用; 

System.out.println("这是"+count+"位数");

这样输入0也会被执行,只不过到while的时候循环判断不满足条件,就结束。


问题3:计数循环(100开始倒数至0,打印“发射”)

          int count = 100;
            
          do
          {
              System.out.println(count);
              count = count - 1;
          }while(count >= 0);
          
          System.out.println("发射!");

计数循环三问:

循环执行多少次?101次

循环停下来的时候,有没有打印出最后的0?输出

循环结束后,count的实际值是多少?-1

tips:如果要模拟运行一个很大次数的循环,可以模拟较少的循环次数,然后做出推断。


问题4:算平均数

用户输入一系列正整数,最后输“-1“使输入结束。程序计算这些正整数的平均数,输出输入数字的个数和平均数。

拿到任何问题前需要思考的两件事: 变量-->算法-->流程图-->程序
1. 用什么样的数(变量):程序输入了哪些数?计算的过程中,需要哪些数?都需要记录表达;
2. 计算用什么样的步骤(算法):可以用流程图辅助;
        Scanner in = new Scanner(System.in);
        int num = in.nextInt();              // 程序先输入一个数
        int count = 0;                       
        int sum = 0;                     

   while(num != -1)          //“-1“ 相当于开关,当不是-1就进循环,输入-1就停止
   {
       sum += num;           // 要用 num += num 就会把第一个输入的数加2次
       count = count + 1;
       num =in.nextInt();    // 程序再录入第2个数(如果只在循环外面那层写,就只会录进第1个数,然后一直循环
   }
   System.out.println("平均数="+(double) sum/count);

小问题

假如程序一开始输入的第一个数就是“-1”的话,不进循环,count = 0(分母),程序结果为“平均数=NaN”。

需要增加一个输出的条件 if(count > 0)。

另外,输出的时候 (double)(sum/count) 与 (double) sum/count 的结果是不一样的!不能加()。

完整代码:

        Scanner in = new Scanner(System.in);
        int num = in.nextInt();
        int count = 0;
        double sum = 0;

   while(num != -1)
   {
       sum += num;
       count = count + 1;
       num =in.nextInt();
   }
   if(count > 0)       //大于0的时候才输出平均数
   {
       System.out.println("平均数=" + (sum / count));
   }

用do...while...也可以来实现,并且避免while里面出现两次 in.nextInt()的情况。但要注意,输入第1次为-1的时候,

sum和count不计算。

            Scanner in = new Scanner(System.in);
            int num;
            int count = 0;
            double sum = 0;

            do
            {
                    num = in.nextInt();
                    if(num != -1)             // 套一个if 
                    {
                    sum += num;
                    count = count + 1;
                    }
            } while(num != -1);

            if(count > 0)       //大于0的时候才输出平均数
            {
                System.out.println("平均数=" + (sum / count));
            }

问题5:猜数游戏

让计算机先想一个数,然后用户来猜,用户每输入一个数,就告诉它是大了还是小了,直到猜中为止,最后告诉用

户他猜了多少次。

思路

输入:计算机随机生成一个数,范围自定。这里设置为[1,20];myInt001

读取用户输入的数;my Int002

还有一个计数的变量;count

计算:首先考虑到用分段条件if...else if...else,将“猜中”、“猜小了”、“猜大了”三种情况分开。因为没有猜中需要

一直循环,所以要用while或者do...while...。又考虑到如果用户第一次就猜中的情况,用尝试do...while...循环条件

限制为while(myInt001 != myInt002)。

输出:将每次的判断结果输出,告诉用户猜大了还是小了。用户猜中后,告诉其一共猜了多少次。

        Random random = new Random();
        int myInt001 = random.nextInt(20-1+1)+1;     //随机的数 myInt001 范围[1-20]上限-下限+1+下限
        Scanner scanner = new Scanner(System.in);
        int myInt002;                                //猜的数 myInt002
        int count=0;

        do
        {
            myInt002 = scanner.nextInt();           
            count ++;                               //输入多少次,就是猜了多少次

            if(myInt001 > myInt002)
            {
                System.out.println("猜小了,请继续猜:");
            }
            else if(myInt001 < myInt002)
            {
                System.out.println("猜大了,请继续猜:");
            }
            else
            {
                System.out.println("猜对了!你共猜了"+count+"次");
            }
        }while (myInt001 != myInt002);

如果用while循环,遇到猜中的情况,甭管是第一次还是若干次后,直接在循环体外输出。分段可以减省为 if...else

if...(最后一个else不用写了)。此外,count的计数次数不受影响。因为初始 myDouble002=5e-6 是一个很小的

浮点数,肯定会满足 myInt001 != myDouble002,从而进入循环体,直到myDouble被用户输入的数字替换掉。用

户输入多少次,就是猜了多少次。如果想法有问题,欢迎留言~

        Random random = new Random();
        int myInt001 = random.nextInt(20-1+1)+1;
        Scanner scanner = new Scanner(System.in);
        double myDouble002=5e-6;                        // 5*10的负6次方 初始是一个非常小的浮点数,不影响随机生成的整数
        int count=0;

        while (myInt001 != myDouble002)
        {
            myInt002 = scanner.nextInt();
            count ++;
            if(myInt001 > myDouble002)
            {
                System.out.println("猜小了,请继续猜:");
            }
            else if(myInt001 < myDouble002)
            {
                System.out.println("猜大了,请继续猜:");
            }
        }
        System.out.println("猜对了!你共猜了"+count+"次");

tips:随机数生成还可以用Math的方法int myInt001 = (int)(Math.random()*100+1(因为Math.random生成的数的范围为[0,1)-->[0,100)-->[1,100]。


问题6:整数分解

一个整数由多位数字组成,如何分解出整数的各个位上的数字(默认从右往左数位数)

例如:
846输出结果如下:
从右往左,第1位上的数字是:6
从右往左,第2位上的数字是:4
从右往左,第3位上的数字是:8

思路

参考【问题2】

首先,如果一个整数%10,取余结果就是第1位(个位)上的数。

同时,拿这个整数/10,得到的商,再%10取余。结果就是第 count+1 位上的数(count 记录为“除以10的次数”)。

最后,while循环的条件如果包括num=0的话,有2种情况,一是num一开始就等于0 ,另外一种是num循环几次后变成0。第二种情况的时候,0会一直循环下去。所以循环条件用num!=0,作为开关。但这样第一种情况num本身就为0的情况,却进不去循环,所以调整用do...while...

public static void main(String[] args) {

        Scanner in = new Scanner(System.in);
        int num = in.nextInt();
        int count = 0;

        do
         {
            count = count +1;
            System.out.println("从右往左,第" + count  + "位上的数字是:" + Math.abs(num % 10));
            num /= 10;
         }while (Math.abs(num) > 0);
}

用Math.abs()就是假如为负数也可以显示,所以输入整数的符号是不是在一开始就要判断一下。

上面的情况,如果需要将整数按照逆序方式输出。

例如:8543
输出:3 4 5 8

循环的条件是 num > 0,每次循环体内将 num 的个位数字取出并输出,再将 num 的值更新为 num/10,即去掉个位数字。

        Scanner in = new Scanner(System.in);
        System.out.print("请输入一个整数:");
        int num = in.nextInt();

            while (Math.abs(num) > 0) {
                System.out.println(Math.abs(num) % 10 + " ");
                num /= 10;
            }
            System.out.println()     //用in.close也可以

// 输出结果 
3 
4 
5 
8

到此,while...和do...while的小例子举完了,下一节会写另外一个循环结构for循环~

如果以上有问题,欢迎留言~

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值