16-程序循环之 while 语句
0. 目录
- 用 while 语句增强找整除数的程序
- do-while 语句——至少执行一次
- 死循环(endless loop)
- 一个看似死循环却不是死循环的例子
- 使用 break 语句结束循环
1. 用 while 语句增强找整除数的程序
1.1 增强点:找出 n 个可以被整除的数
while 语句的语法
- 条件表达式的结果是一个 boolean 值,如果为 true,则执行循环体,如果为 false,则循环结束。
- While 循环体是一个代码块。所以 while 循环也是可以嵌套别的语句的,包括 while 语句,for 语句,if-else 语句等。
while (条件表达式){
while 循环体
}
public class FindNDiv {
public static void main(String[] args) {
int n = 10;
// int n = -1;
int dividend = 100; // 被除数
int divisor = 89; // 除数
int found = 0;
while (found < n) {
if (dividend % divisor == 0) {
System.out.println(dividend + "可以整除" + divisor + "。商是" + dividend / divisor);
found++;
}
dividend++;
}
}
}
输出:
/Library/Java/JavaVirtualMachines/jdk-11.0.2.jdk/Contents/Home/bin/java -javaagent:/Applications/IntelliJ IDEA.app/Contents/lib/idea_rt.jar=52087:/Applications/IntelliJ IDEA.app/Contents/bin -Dfile.encoding=UTF-8 -classpath /Users/huangjiabao/GitHub/Java_Coder/Coder16/out/production/Coder16 FindNDiv
178可以整除89。商是2
267可以整除89。商是3
356可以整除89。商是4
445可以整除89。商是5
534可以整除89。商是6
623可以整除89。商是7
712可以整除89。商是8
801可以整除89。商是9
890可以整除89。商是10
979可以整除89。商是11
Process finished with exit code 0
2. do-while 语句——至少执行一次
2.1 语法
- do-while 语句语法
- do-while 语句的循环体至少执行一次
do{
while 循环体
} while (条件表达式);
public class DoWhileExample {
public static void main(String[] args) {
do {
System.out.println("会执行一次");
} while (false);
}
}
public class DoWhileExample {
public static void main(String[] args) {
// 在条件为假的情况下,for 语句或 while 语句都不会执行
for (int i = 0; i > 90; i++) {
System.out.println("一次都不会执行");
}
}
}
从本人的编程经验来看, do......while...... 用到的情况比较少。
我们既然说了循环,那我们就离不开一个概念:死循环。
2.2 练习
2.2.1 打印1到100的奇数
编写一个程序,使用 do...while
循环打印1到100之间的所有奇数。
public class OddNumbers {
public static void main(String[] args) {
int i = 1; // 从1开始
do {
if (i % 2 != 0) { // 判断是否为奇数
System.out.println(i); // 输出奇数
}
i++; // 递增i
} while (i <= 100); // 当i小于等于100时继续循环
}
}
2.2.2 猜数字游戏
编写一个程序,模拟一个猜数字的游戏,计算机生成一个1到100之间的随机数,用户通过输入猜测该数字,程序在每次猜测后告诉用户猜得是否正确,直到用户猜对为止。
import java.util.Scanner;
public class GuessNumber {
public static void main(String[] args) {
int secretNumber = (int) (Math.random() * 100) + 1; // 随机生成1到100之间的数
int guess;
Scanner scanner = new Scanner(System.in);
do {
System.out.print("请输入你的猜测 (1-100): ");
guess = scanner.nextInt(); // 读取用户输入的猜测值
if (guess > secretNumber) {
System.out.println("猜大了!再试一次。");
} else if (guess < secretNumber) {
System.out.println("猜小了!再试一次。");
}
} while (guess != secretNumber); // 当猜对时退出循环
System.out.println("恭喜你,猜对了!");
}
}
2.2.3 计算输入数字的和
编写一个程序,要求用户输入多个正整数,使用 do...while
循环计算输入数字的总和,直到用户输入负数为止,负数输入时结束输入并显示总和。
import java.util.Scanner;
public class SumNumbers {
public static void main(String[] args) {
int sum = 0; // 用于存储总和
int number;
Scanner scanner = new Scanner(System.in);
do {
System.out.print("请输入一个正整数(输入负数结束):");
number = scanner.nextInt(); // 读取用户输入的数字
if (number >= 0) {
sum += number; // 如果数字为正,则累加到总和
}
} while (number >= 0); // 当输入为负数时退出循环
System.out.println("输入的数字总和是: " + sum);
}
}
2.2.4 输出乘法表
编写一个程序,输出1到9的乘法表,使用 do...while
循环控制行数和列数。
public class MultiplicationTable {
public static void main(String[] args) {
int i = 1, j;
do {
j = 1;
do {
System.out.print(i * j + "\t"); // 输出乘法表的每个值
j++;
} while (j <= 9);
System.out.println(); // 换行
i++;
} while (i <= 9); // 控制1到9的行数
}
}
2.2.5 判断素数
编写一个程序,判断输入的一个正整数是否为素数,要求使用 do...while
循环来进行判断。如果是素数,输出 “是素数”,否则输出 “不是素数”。
import java.util.Scanner;
public class PrimeNumber {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("请输入一个正整数: ");
int number = scanner.nextInt();
boolean isPrime = true; // 假设该数是素数
if (number <= 1) {
isPrime = false; // 小于等于1的数不是素数
} else {
int i = 2;
do {
if (number % i == 0) { // 如果能够被i整除,说明不是素数
isPrime = false;
break; // 提前退出循环
}
i++;
} while (i <= Math.sqrt(number)); // 判断到平方根即可
}
if (isPrime) {
System.out.println(number + " 是素数");
} else {
System.out.println(number + " 不是素数");
}
}
}
2.2.6 密码输入验证
编写一个程序,要求用户输入密码。密码正确(假设为 "1234")时,输出“密码正确”,否则,提示“密码错误”,并让用户重新输入,直到密码正确为止。
import java.util.Scanner;
public class PasswordCheck {
public static void main(String[] args) {
String correctPassword = "1234"; // 设置正确密码
String inputPassword;
Scanner scanner = new Scanner(System.in);
do {
System.out.print("请输入密码: ");
inputPassword = scanner.nextLine(); // 获取用户输入的密码
if (!inputPassword.equals(correctPassword)) {
System.out.println("密码错误,请重新输入!");
}
} while (!inputPassword.equals(correctPassword)); // 密码正确时退出循环
System.out.println("密码正确,欢迎进入系统!");
}
}
3. 死循环(endless loop)
- 死循环:无法结束的循环( endless loop / infinite loop)
- 一个死循环的例子
- 死循环是因为没有设置好结束条件「下面没有设置 found + 1」,循环的结束条件很重要,要充分考虑各种边界情况。
public class FindNDivEndless {
public static void main(String[] args) {
int n = 5;
int dividend = 100;
int divisor = 89;
int found = 0;
while (found < n) {
if (dividend % divisor == 0) {
System.out.println(dividend + "可以整除" + divisor + "。商是" + dividend / divisor);
}
dividend++;
}
}
}
4. 一个看似死循环却不是死循环的例子
- 用 while 找出 5个能被 2,000,000,000 整除的数
- 程序最终还是结束了,但是结果并不是我们想要的
public class FindNDivNotEndless {
public static void main(String[] args) {
int n = 5;
int dividend = 100;
int divisor = 2000000000;
int found = 0;
while (found < n) {
if (dividend % divisor == 0) {
System.out.println(dividend + "可以整除" + divisor + "。商是" + dividend / divisor);
found++;
}
dividend++;
}
}
}
2000000000可以整除2000000000。商是1
-2000000000可以整除2000000000。商是-1
0可以整除2000000000。商是0
2000000000可以整除2000000000。商是1
-2000000000可以整除2000000000。商是-1
这其实是整数的加法溢出,我们之前也提过。如果你对一个整数一直加 1 的话,最后就会变成负数。然后再加加就变成正数。它会这样循环,所以说这是个问题。这是计算和数学的区别,数学是没有这种边界问题的。数学中,这个数字可以无限大,那计算就只有这 4 个 byte。超出范围是不可控、不可知的。1 int = 4 byte
,1 byte = 8 bit
。
5. 使用 break 语句结束循环
- break 语句可以结束任何循环
- 不考虑负数的情况,使用 break 改善程序「比如程序 ++ 出现负数,就可以食用 break 跳出循环,避免程序做一些无谓的运算」
- 理解 String start 的内容,为什么不是“从 -2147483648 开始递增”
public class FindNDivBetter {
public static void main(String[] args) {
int n = 5;
int dividend = 100;
int divisor = 2000000000;
String start = "从" + dividend + "开始递增,";
int found = 0;
while (found < n) {
if (dividend < 0) {
System.out.println("被除数溢出,未找到足够的数。循环结束。");
break;
}
if (dividend % divisor == 0) {
System.out.println(dividend + "可以整除" + divisor + "。商是" + dividend / divisor);
found++;
}
dividend++;
}
System.out.println(start + "共找到" + found + "个可以整除" + divisor + "的数。");
System.out.println(dividend);
}
}
2000000000可以整除2000000000。商是1
被除数溢出,未找到足够的数。循环结束。
从100开始递增,共找到1个可以整除2000000000的数。
-2147483648
为什么是从100,而不是从-2147483648 开始?举个简单的例子就可以:就像一个印章,你盖完之后。别人把印章再修修改改其实也不会影响到已经盖完的。
6. while 循环编程题
6.1 打印 1 到 10 的数字
编写一个程序,使用 while
循环打印出 1 到 10 的数字,每行输出一个数字。
示例输出:
1
2
3
4
5
6
7
8
9
10
答案:
public class PrintNumbers {
public static void main(String[] args) {
int i = 1;
while (i <= 10) {
System.out.println(i);
i++;
}
}
}
6.2 计算数字之和
编写一个程序,让用户输入一系列的正整数,当用户输入负数时结束输入。程序应该使用 while
循环累加所有正整数的和,并在用户输入负数后输出总和。
示例输入:
输入:5 3 8 2 -1
示例输出:
和:18
答案:
public class PrintNumbers {
public static void main(String[] args) {
int i = 1;
while (i <= 10) {
System.out.println(i);
i++;
}
}
}
6.3 求整数的阶乘
编写一个程序,使用 while
循环计算一个正整数的阶乘。让用户输入一个正整数 n
,程序应输出 n!
的值。
示例输入:
输入:5
示例输出:
5! = 120
答案:
import java.util.Scanner;
public class Factorial {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("请输入一个正整数:");
int n = scanner.nextInt();
int factorial = 1;
int i = 1;
while (i <= n) {
factorial *= i; // 计算阶乘
i++;
}
System.out.println(n + "! = " + factorial);
scanner.close();
}
}
import java.util.Scanner;
public class Factorial {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int userinput = scanner.nextInt();
int total = 1;
while (userinput > 0) {
total = total * userinput;
userinput = userinput - 1;
}
System.out.println(total);
}
}
6.4 求 1 到 n 中所有质数的个数
编写一个程序,用户输入一个正整数 n
,程序需要计算并输出 1 到 n
之间的所有质数的个数。质数是大于 1 的自然数,且只有 1 和它本身两个因数。
提示:
- 使用
while
循环遍历从 2 到n
的每个数字。 - 对于每个数字,检查它是否为质数。可以通过判断该数字是否能被小于它的其他数字整除来确定。
- 如果是质数,增加计数。
示例输入:
请输入一个正整数 n: 20
示例输出:
1 到 20 之间的质数个数是:8
参考代码:
import java.util.Scanner;
public class PrimeCount {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// 让用户输入一个正整数 n
System.out.print("请输入一个正整数 n: ");
int n = scanner.nextInt();
// 质数个数
int primeCount = 0;
// 从 2 开始遍历到 n
int num = 2;
while (num <= n) {
int divisor = 2;
boolean isPrime = true; // 假设当前数字是质数
// 检查 num 是否是质数
while (divisor <= Math.sqrt(num)) { // 只需检查到平方根
if (num % divisor == 0) {
isPrime = false; // 如果能被整除,就不是质数
break;
}
divisor++;
}
// 如果是质数,增加计数
if (isPrime) {
primeCount++;
}
num++;
}
// 输出质数的个数
System.out.println("1 到 " + n + " 之间的质数个数是:" + primeCount);
scanner.close();
}
}
代码分析:
- 我们从 2 开始遍历到用户输入的
n
。 - 对于每个数字
num
,通过内部的while
循环检查它是否能被除 2 到sqrt(num)
之间的任何数字整除。若能整除,则该数字不是质数。 - 如果
num
是质数,则增加计数器primeCount
。 - 使用
Math.sqrt(num)
来减少检查的次数,只需要检查到num
的平方根即可,这样优化了算法性能。
示例输出:
输入:
请输入一个正整数 n: 20
输出:
1 到 20 之间的质数个数是:8
欢迎关注我公众号:AI悦创,有更多更好玩的等你发现!
公众号:AI悦创【二维码】

AI悦创·编程一对一
AI悦创·推出辅导班啦,包括「Python 语言辅导班、C++ 辅导班、java 辅导班、算法/数据结构辅导班、少儿编程、pygame 游戏开发」,全部都是一对一教学:一对一辅导 + 一对一答疑 + 布置作业 + 项目实践等。当然,还有线下线上摄影课程、Photoshop、Premiere 一对一教学、QQ、微信在线,随时响应!微信:Jiabcdefh
C++ 信息奥赛题解,长期更新!长期招收一对一中小学信息奥赛集训,莆田、厦门地区有机会线下上门,其他地区线上。微信:Jiabcdefh
方法一:QQ
方法二:微信:Jiabcdefh
