c语言小课堂-do-while

c语言小课堂-do-while
TANG JIAMEI编程的世界里,循环语句就像是我们的“重复执行器”,能帮我们高效地完成大量重复性任务。今天,我们要深入了解一个有点“特别”的循环——do-while
语句。它不像你可能熟悉的 while
和 for
循环那样“先看后做”,而是有点“不回头”的执着,先做一次再说!
一、do-while 语句:先做再说,至少一次!
1. 是什么?
do-while
循环是 C 语言提供的一种后测试循环结构。它的基本语法如下:
1 | do { |
do
关键字:表示循环体的开始。- 循环体:包含了一组需要重复执行的语句。
while (条件表达式)
:在循环体执行完毕后,才会对条件表达式进行判断。- 分号
;
:这是do-while
循环特有的,while
后必须跟着一个分号,表示循环语句的结束。
与 while
循环(先判断条件,再执行循环体)不同,do-while
循环的特点是无论条件表达式是否为真,循环体至少会执行一次。 只有在第一次执行完毕后,才会检查条件表达式。如果条件为真,则继续执行下一次循环;如果条件为假,则退出循环。
2. 何时用?
do-while
循环在编程中扮演着独特的角色,尤其适用于以下场景:
- 至少执行一次的场景:这是
do-while
最核心的应用场景。例如,要求用户输入一个有效值,如果输入无效则一直提示重新输入,直到输入有效为止。无论用户第一次输入什么,我们都希望至少给他们一次输入的机会。 - 用户交互菜单:在构建基于文本的菜单程序时,
do-while
循环非常方便。我们可以先显示菜单并获取用户选择,然后根据选择判断是否继续显示菜单或执行其他操作。 - 需要初始化后才能判断的场景:有些情况下,循环的条件判断依赖于循环体内部产生的值。例如,计算一个序列的和,你需要先执行一次循环来产生第一个值,然后才能根据这个值来判断是否继续。
与 while
循环的区别与联系:
特性 | while 循环 |
do-while 循环 |
---|---|---|
测试时机 | 先测试条件,后执行循环体 | 先执行循环体,后测试条件 |
执行次数 | 循环体可能执行 0 次或多次 | 循环体至少执行 1 次或多次 |
应用场景 | 适用于循环体可能不需要执行的场景 | 适用于循环体至少需要执行一次的场景 |
语法 | while (条件) { ... } |
do { ... } while (条件); |
简单来说,如果你确定你的代码逻辑至少要执行一次,那么 do-while
就是你的不二选择。如果你不确定是否需要执行,或者可能一次都不需要执行,那么 while
或 for
循环会更合适。
3. 怎么用?
让我们通过几个实际例子来感受 do-while
的魅力。
示例一:用户输入校验
1 |
|
代码解析:
在这个例子中,无论用户第一次输入什么,程序都会先执行 scanf
获取分数。然后,while
语句会检查分数是否在有效范围内。如果不在,就会继续循环,直到用户输入一个有效分数为止。
示例二:简单的菜单选择
1 |
|
代码解析:
这个程序会先显示菜单并获取用户选择,然后根据选择执行相应的操作。如果用户输入的不是 3
(退出),do-while
循环就会再次执行,重新显示菜单,直到用户选择退出为止。这确保了菜单至少会显示一次。
示例三:计算 1 到 n 的和(使用 do-while)
1 |
|
代码解析:
这个例子展示了如何使用 do-while
来累加。即使 n
为 1,循环体也会至少执行一次(sum += 1; i++
),然后 i
变为 2,i <= n
(2 <= 1) 为假,循环退出。确保了即使只计算 1 到 1 的和,也能正确执行。
二、配套习题设计
习题一(选择题)
以下关于 do-while
循环的描述,哪一项是正确的?
A. do-while
循环的循环体可能一次都不执行。
B. do-while
循环的条件表达式在循环体执行之前判断。
C. do-while
循环的 while
后面必须带分号。
D. do-while
循环通常用于已知循环次数的场景。
习题二(判断题)
do-while
循环可以完全被 while
循环替代,且不改变程序的行为。
( )
习题三(填空题)
请填写代码,使得该 do-while
循环能够打印数字 5 到 1,然后结束。
1 |
|
习题四(编程题)
编写一个 C 语言程序,使用 do-while
循环实现一个简单的猜数字游戏。
程序随机生成一个 1 到 100 之间的整数,然后提示用户输入猜测的数字。
如果用户猜错了,程序会提示“太大了”或“太小了”,直到用户猜对为止。
每当用户猜对后,程序应显示“恭喜你,猜对了!”并显示用户猜测的次数。
提示:
- 使用
rand()
函数生成随机数,需要包含<stdlib.h>
和<time.h>
。 - 使用
srand(time(NULL))
初始化随机数种子。
习题五(编程题)
编写一个 C 语言程序,使用 do-while
循环计算并打印斐波那契数列(Fibonacci sequence)的前 N 项。斐波那契数列的定义是:F(0) = 0, F(1) = 1, F(n) = F(n-1) + F(n-2) (n >= 2)。程序应确保用户输入的 N 是一个正整数(大于等于 1)。
要求:
- 提示用户输入要打印的斐波那契数列项数 N。
- 使用
do-while
循环确保用户输入的 N 是一个大于等于 1 的整数。 - 使用
do-while
循环计算并打印斐波那契数列的前 N 项。 - 如果 N 为 1,只打印 0;如果 N 为 2,打印 0 1。
三、习题讲解
习题一(选择题)
以下关于 do-while
循环的描述,哪一项是正确的?
A. do-while
循环的循环体可能一次都不执行。
B. do-while
循环的条件表达式在循环体执行之前判断。
C. do-while
循环的 while
后面必须带分号。
D. do-while
循环通常用于已知循环次数的场景。
答案:C
解析:
- A 选项错误:
do-while
循环的特点是先执行循环体,后判断条件,所以循环体至少会执行一次。 - B 选项错误:
do-while
循环是后测试循环,条件表达式在循环体执行之后才判断。 - C 选项正确:这是
do-while
语法的强制要求,while (条件表达式);
后面必须有一个分号。 - D 选项错误:
do-while
循环通常用于循环次数不确定,但至少需要执行一次的场景,例如用户输入校验。已知循环次数的场景更适合使用for
循环。
习题二(判断题)
do-while
循环可以完全被 while
循环替代,且不改变程序的行为。
( )
答案:F (错误)
解析:do-while
循环和 while
循环的主要区别在于循环体执行的次数。do-while
循环保证循环体至少执行一次,而 while
循环在条件不满足时可能一次都不执行。
虽然我们可以通过在 while
循环前复制一份循环体的代码,来模拟 do-while
至少执行一次的行为,例如:
1 | // do-while |
但这种替代方式并不“完全”且“不改变程序的行为”,因为它引入了代码重复,并且在逻辑上不如 do-while
语句直接清晰地表达“至少执行一次”的意图。在某些情况下,如果条件一开始就为假,while
循环将不执行,而 do-while
依然会执行一次,这时它们的行为就不同了。因此,不能说它们可以完全互相替代而不改变程序的行为。
习题三(填空题)
请填写代码,使得该 do-while
循环能够打印数字 5 到 1,然后结束。
1 |
|
答案:num = 5;
num >= 1;
解析:
- 我们希望从 5 开始打印,所以
num
的初始值应设为 5。 - 循环体每次打印
num
并将其减 1。 - 循环需要持续到
num
变为 1 也要打印,然后当num
减到 0 时停止。因此,循环条件应该是num >= 1
。当num
变为 0 时,条件0 >= 1
为假,循环终止。
习题四(编程题)
题目: 编写一个 C 语言程序,使用 do-while
循环实现一个简单的猜数字游戏。程序随机生成一个 1 到 100 之间的整数,然后提示用户输入猜测的数字。如果用户猜错了,程序会提示“太大了”或“太小了”,直到用户猜对为止。每当用户猜对后,程序应显示“恭喜你,猜对了!”并显示用户猜测的次数。
代码:
1 |
|
解析:
- 随机数生成:
srand(time(NULL))
用于初始化随机数生成器,确保每次运行程序时都能生成不同的随机数。randomNumber = (rand() % 100) + 1;
生成 1 到 100 之间的整数。 do-while
的应用: 游戏至少要让用户猜一次,所以do-while
循环非常适合。do
块内包含获取用户输入、增加猜测次数和判断猜测结果的逻辑。- 循环条件:
while (guess != randomNumber);
表示只要用户猜的数字不等于随机数,循环就会继续执行。一旦猜对,条件guess != randomNumber
为假,循环终止。 - 计数器:
guessCount
变量在每次用户猜测后递增,用于记录猜测次数。
习题五(编程题)
题目: 编写一个 C 语言程序,使用 do-while
循环计算并打印斐波那契数列(Fibonacci sequence)的前 N 项。斐波那契数列的定义是:F(0) = 0, F(1) = 1, F(n) = F(n-1) + F(n-2) (n >= 2)。程序应确保用户输入的 N 是一个正整数(大于等于 1)。
代码:
1 |
|
解析:
用户输入校验 (
do-while
第一次应用):- 外层的
do-while
循环do { ... } while (n < 1);
用于确保用户输入的n
是一个大于等于 1 的正整数。无论用户第一次输入什么,程序都会执行一次输入提示和获取。如果输入无效,它会继续提示,直到输入有效为止。
- 外层的
斐波那契数列计算与打印 (
do-while
第二次应用):- 初始化:
a
和b
分别初始化为斐波那契数列的前两项 F(0) = 0 和 F(1) = 1。nextTerm
用于存储下一项的值,count
用于记录当前已打印的项数。 - 特殊情况处理: 由于斐波那契数列的定义是 F(0) 和 F(1) 是固定的,从 F(2) 开始才由前两项相加得到,所以需要对
n=1
和n=2
进行特殊处理,直接打印 F(0) 和 F(0) F(1)。 - 循环打印: 当
n >= 2
时,在打印了 F(0) 和 F(1) 后,count
初始化为 2。- 内部的
do-while
循环do { ... } while (count < n);
开始计算并打印从第三项开始的斐波那契数。 - 每次循环:
nextTerm = a + b;
计算下一项。printf("%lld ", nextTerm);
打印当前项。a = b;
和b = nextTerm;
更新a
和b
的值,为下一次循环做准备。count++;
增加已打印项数。
- 循环条件
count < n
确保循环继续执行直到打印了n
项。即使n=2
并且已经打印了 0 1,这个do-while
循环也不会执行(因为count
已经等于n
),这符合预期。
- 内部的
- 初始化:
数据类型: 使用
long long
来存储斐波那契数,因为斐波那契数列增长非常快,int
类型很快就会溢出。
通过这两个编程题,你是不是对 do-while
循环的“至少执行一次”特性有了更深刻的理解呢?记住,选择合适的循环结构是写出高效、清晰代码的关键哦!