循环重复:while 语句的使用与应用
1. 使用 while 语句绘制同心圆
1.1 程序初始化
我们可以使用 while 语句来绘制一系列直径逐渐增大的同心圆。具体操作步骤如下:
1. 选择“文件”>“新建”来开始一个新程序,并将其保存为“Concentric”。
2. 设置画布大小为 150 像素×150 像素,代码如下:
size(150, 150);
-
创建一个变量
diameter
来跟踪圆的直径变化,并将初始直径设置为 20 像素:
int diameter;
diameter = 20;
-
再创建一个变量
step
来记录每次直径增加的量,初始步长设置为 10 像素:
int step;
step = 10;
- 关闭圆的填充,并将笔触粗细设置为 3 像素:
noFill();
strokeWeight(3);
- 添加语句以在控制台显示当前直径,并在画布中心绘制具有当前直径的圆:
println(diameter);
ellipse(width / 2, height / 2, diameter, diameter);
1.2 增加直径并使用 while 循环
为了绘制越来越大的圆,我们需要添加语句来增加直径:
println(diameter);
ellipse(width / 2, height / 2, diameter, diameter);
diameter = diameter + step;
这里使用了赋值语句,赋值运算符(
=
)两侧使用了相同的变量名。为了便于理解,也可以写成
diameter = (diameter + step);
。
为了持续显示当前直径、绘制圆并增加直径,我们将这三个语句包裹在一个 while 循环中:
while (diameter < width)
{
println(diameter);
ellipse(width / 2, height / 2, diameter, diameter);
diameter = diameter + step;
}
循环条件
diameter < width
表示只要圆的直径小于画布宽度,循环就会继续执行。当直径大于或等于画布宽度时,循环条件变为
false
,循环结束。
运行该程序时,控制台会显示直径的值,每次增加 10 像素,直到直径达到或超过 150 像素。同时,画布上会显示一系列同心圆,产生“莫尔效应”的视觉效果。
1.3 注释与取消注释
在调试程序时,每次循环在控制台输出信息有助于跟踪循环的执行情况。但当程序正常运行后,若不需要这些输出,可以通过在每行开头添加两个斜杠(
//
)将这些语句转换为注释。例如:
while (diameter < width)
{
// println(diameter);
ellipse(width / 2, height / 2, diameter, diameter);
diameter = diameter + step;
}
这被称为“注释掉”一行代码,比直接删除代码更好,因为后续若需要再次跟踪循环,只需移除开头的两个斜杠即可“取消注释”。在 Processing 中,可以通过选择代码行,然后从“编辑”菜单中选择“注释/取消注释”或使用快捷键
Ctrl-/
来轻松实现注释和取消注释操作。
以下是绘制同心圆程序的完整代码:
size(150, 150);
int diameter;
diameter = 20;
int step;
step = 10;
noFill();
strokeWeight(3);
while (diameter < width)
{
println(diameter);
ellipse(width / 2, height / 2, diameter, diameter);
diameter = diameter + step;
}
1.4 流程图
graph TD;
A[开始] --> B[初始化画布和变量];
B --> C{直径 < 画布宽度};
C -- 是 --> D[显示直径并绘制圆];
D --> E[增加直径];
E --> C;
C -- 否 --> F[结束];
2. 使用 while 语句创建交互式猜数字游戏
2.1 程序初始化
我们可以创建一个猜数字游戏,让玩家猜测 1 到 10 之间的一个数字。具体步骤如下:
1. 选择“文件”>“新建”创建一个新程序,并将其保存为“Guess”。
2. 插入
import
语句以支持输入和消息对话框:
import static javax.swing.JOptionPane.*;
-
创建一个
String
变量input
来存储玩家的输入:
String input;
-
创建一个
int
变量guess
来存储玩家猜测的整数,初始化为 0:
int guess;
guess = 0;
-
创建一个
int
变量secret
来存储随机生成的秘密数字,范围是 1 到 10:
int secret;
secret = int( random(1, 11) );
-
创建一个
String
变量prompt
来存储提示信息:
String prompt;
prompt = "Guess a number from 1 to 10:";
-
生成一个输入对话框,提示玩家猜测数字,并将玩家输入的
String
值存储到input
变量中:
input = showInputDialog(prompt);
-
将玩家输入的
String
值转换为int
值,并存储到guess
变量中:
guess = int(input);
2.2 使用 while 循环实现猜测逻辑
为了在玩家猜测错误时继续提示玩家猜测,我们使用
while
循环:
while (guess != secret)
{
input = showInputDialog(prompt);
guess = int(input);
}
不过,当前的游戏难度较大,我们可以根据玩家的猜测结果给出更具体的提示。如果猜测的数字太低,提示玩家猜更高的数字;如果猜测的数字太高,提示玩家猜更低的数字;如果猜测正确,则显示正确信息。代码如下:
while (guess != secret)
{
input = showInputDialog(prompt);
guess = int(input);
if (guess < secret)
{
prompt = "Guess a HIGHER number (1 to 10):";
}
else if (guess > secret)
{
prompt = "Guess a LOWER number (1 to 10):";
}
else
{
prompt = "Correct! The secret number is: " + secret;
}
}
当玩家猜对数字时,循环结束,此时显示一个消息对话框告知玩家猜测正确:
showMessageDialog(frame, prompt);
以下是猜数字游戏的完整代码:
import static javax.swing.JOptionPane.*;
String input;
int guess;
guess = 0;
int secret;
secret = int( random(1, 11) );
String prompt;
prompt = "Guess a number from 1 to 10:";
while (guess != secret)
{
input = showInputDialog(prompt);
guess = int(input);
if (guess < secret)
{
prompt = "Guess a HIGHER number (1 to 10):";
}
else if (guess > secret)
{
prompt = "Guess a LOWER number (1 to 10):";
}
else
{
prompt = "Correct! The secret number is: " + secret;
}
}
showMessageDialog(frame, prompt);
2.3 流程图
graph TD;
A[开始] --> B[初始化变量];
B --> C[显示提示并获取输入];
C --> D{猜测是否正确};
D -- 否 --> E{猜测 < 秘密数字};
E -- 是 --> F[提示猜更高的数字];
E -- 否 --> G[提示猜更低的数字];
F --> C;
G --> C;
D -- 是 --> H[显示正确信息];
H --> I[结束];
3. 逻辑非(!)运算符及其在 while 循环中的应用
3.1 逻辑非(!)运算符的基本概念
Processing 使用感叹号(!)作为逻辑非(NOT)运算符,该运算符可用于创建布尔值、变量或表达式的逻辑相反值(即取反)。例如,假设
roll
变量的值为 5,那么布尔表达式
(roll > 3)
计算结果为
true
。而逻辑非操作(!)会产生其后面任何布尔表达式的逻辑相反值,所以
!(roll > 3)
计算结果为
false
。
3.2 使用逻辑非(!)修改 while 循环的停止条件
Processing 的
while
语句要求我们从“只要”的角度来思考循环,而不是“直到”。但有时,从“直到某个条件为真才停止循环”的角度思考会更直观。在这种情况下,可以使用逻辑非(!)操作来创建这样的
while
循环。
以
RollWhile
程序为例,我们将其另存为
RollWhileNot
。原程序中,
while
循环定义为只要
roll
不等于 6 就继续执行循环体中的语句:
int roll;
roll = int( random(1, 7) );
println("First roll: " + roll);
while (roll != 6)
{
roll = int( random(1, 7) );
println("Roll again: " + roll);
}
println("Game over.");
如果我们更倾向于从“直到掷出 6 才停止循环”的角度思考,那么停止条件就是
roll == 6
。我们可以通过在停止条件前加上逻辑非(!)运算符,将其转换为
while
语句所需的继续条件:
int roll;
roll = int( random(1, 7) );
println("First roll: " + roll);
while ( !(roll == 6) )
{
roll = int( random(1, 7) );
println("Roll again: " + roll);
}
println("Game over.");
运行这个程序,我们会发现循环仍然会重复,直到掷出 6 时停止。这表明,当我们更直观地从停止条件思考时,可以使用逻辑非运算符(!)来创建
while
循环。
3.3 逻辑非应用的流程图
graph TD;
A[开始] --> B[初始化变量并掷第一次骰子];
B --> C{骰子点数是否为 6};
C -- 否 --> D[再次掷骰子并显示点数];
D --> C;
C -- 是 --> E[游戏结束];
4. do - while 语句的使用
4.1 do - while 语句的基本概念
Processing 还支持另一种类似于
while
循环的结构:
do - while
语句。
do - while
语句也被称为后置测试或底部测试循环,因为决定循环是否继续的条件是在循环体中的语句执行之后进行检查的。这意味着
do - while
循环体中的语句至少会执行一次。其基本形式如下:
do
{
// 要重复执行的语句
}
while (条件);
注意,
do - while
语句结尾需要一个分号。
4.2 将 while 循环转换为 do - while 循环
我们再次以
RollWhile
程序为例,将其另存为
RollDoWhile
。原程序使用
while
语句实现循环:
int roll;
roll = int( random(1, 7) );
println("First Roll: " + roll);
while (roll != 6)
{
roll = int( random(1, 7) );
println("Roll again: " + roll);
}
println("Game Over!");
将其转换为
do - while
循环时,由于
do - while
循环体至少会执行一次,所以不需要在循环开始前单独进行第一次掷骰子的操作。修改后的代码如下:
int roll;
do
{
roll = int( random(1, 7) );
println("Roll: " + roll);
}
while (roll != 6);
println("Game Over!");
运行这个程序,我们会发现它和
while
版本一样,只要掷出的点数不是 6 就会继续模拟掷骰子。在这个例子中,使用
do - while
语句简化了程序。
4.3 do - while 循环的优缺点
一般来说,
do - while
语句不如
while
语句常用。但当我们知道循环中的语句至少需要执行一次时,
do - while
语句有时是构建循环的更简单方式。
4.4 do - while 循环流程图
graph TD;
A[开始] --> B[执行循环体(掷骰子并显示点数)];
B --> C{骰子点数是否为 6};
C -- 否 --> B;
C -- 是 --> D[游戏结束];
总结
本文详细介绍了
while
语句在不同场景下的应用,包括使用
while
语句绘制同心圆、创建交互式猜数字游戏,以及逻辑非(!)运算符在
while
循环中的应用。同时,还介绍了
do - while
语句的特点和使用方法。通过这些示例,我们可以看到不同循环结构的特点和适用场景:
| 循环结构 | 特点 | 适用场景 |
| ---- | ---- | ---- |
|
while
循环 | 先判断条件,条件为真时执行循环体 | 不确定循环体是否需要执行,根据条件决定是否进入循环 |
|
do - while
循环 | 先执行循环体,再判断条件,循环体至少执行一次 | 确定循环体至少需要执行一次的情况 |
在实际编程中,我们可以根据具体需求选择合适的循环结构,以提高代码的可读性和效率。同时,合理使用逻辑非(!)运算符可以使我们从不同的角度思考循环条件,让代码更符合我们的思维习惯。