for 语句
for循环
for
循环语法:
for (循环变量赋初始值;循环条件;更新循环变量) {
循环体
}
语法解析
- 循环变量:用于控制循环的变量,一般在循环条件中使用
- 比如:循环变量可以是在存钱100天这个例子中的天数
- for循环的执行逻辑:
- 首先会给循环变量赋一个初始值
- 然后判断是否满足循环条件
- 如果不满足,直接跳出循环;
- 如果满足,执行循环体,更新循环变量,再跳回去重新判断是否满足循环条件。
- 比如:输出存款总数,天数加1,再跳回去看看现在是不是依然满足循环条件
- 使用for循环时,【循环变量赋初始值】,【循环条件】,【更新循环变量】这三个表达式都可以省略,变为
for ( ; ; )
,这表示不用给循环变量赋初始值,也不用在每次执行后更新循环变量,同时循环的条件始终为真,也就是说每次都会选择进入循环体。 - 如果循环体只有一句话,可以不用大括号括起来
- 举例
存钱100天的程序段:
// 输入一个整型变量表示存款总数量
int savings = 0;
// 用循环变量 i 表示现在的天数
// 最开始为1
// 每次循环后都加1天
// 不满足小于等于100天时就跳出循环
for (int i=1; i<=100; i++) {
// 更新存款总数
savings = savings + i;
// 输出存款总数
cout << i << ":总数" << savings << endl;
}
循环控制语句 break
- 除了正常的循环之外,循环控制语句可以更改程序执行的正常序列。循环控制语句常用的是
break
和continue
。 break
用法- 在
switch
语句中也有用到过,用于停止执行模块内后面的程序语句 - 通常放在循环体中,当执行到这句语句时,跳出整个循环,也就是说整个循环立即终止
- 在
- 举例:
存钱100天的例子,假设迷你键希望当存款总数到1000元时,就不存了,那他可以用break来终止循环
int savings = 0;
for (int i=1; i<=100; i++) {
savings = savings + i;
cout << i << ":总数" << savings << endl;
// 当存到1000元时,跳出循环
if (savings >= 1000)
break;
}
循环控制语句 continue
- 另一个常用的循环控制语句是
continue
。 continue
用法- 通常也是放在循环体中,当执行到这句语句时,跳过当前循环体,强迫进入下一次循环
- 举例:
存钱100天的例子,假设如果天数是10的倍数(第10、20、30、…天),那么那天可以不存钱,也不输出存款总量。他可以用continue
来跳过这几次循环
int savings = 0;
for (int i=1; i<=100; i++) {
// 如果天数是10的倍数,直接进入下一天
if (i % 10 == 0)
continue;
savings = savings + i;
cout << i << ":总数" << savings << endl;
}
练习
-
输出21世纪(2001年1月1日至2100年12月31日的这一段期间称为21世纪)中截止某个年份以来的所有闰年年份。
注意:闰年的判别条件是该年年份能被4整除但不能被100整除,或者能被400整除。
输入描述:
输入在一行中给出21世纪的某个截止年份。
输出描述:
逐行输出满足条件的所有闰年年份,即每个年份占一行。输入若非21世纪的年份则输出"Invalid year!"。若不存在任何闰年,则输出“None”。
#include <bits/stdc++.h> using namespace std; int main() { // 请补全代码,实现题目功能 int year, outYear; bool mark = false; cin >> year; if ((year < 2001)||(year > 2100)){ cout << "Invalid year!" << endl; } else { for (outYear = 2001; outYear <= year; outYear++) { if (!(outYear % 400) || (!(outYear % 4) && (outYear % 100))) { cout << outYear << endl; mark = true; } } if (!mark) { cout << "None" << endl; } } return 0; }
-
给定大于1的整数n,求[1,n]区间上的数字之和。
输入描述:
一行,一个整数n
输出描述:
一行,数字之和
#include <bits/stdc++.h> using namespace std; int main() { // 请补全代码,实现题目功能 int i, n, sum; cin >> n; sum = 0; for (i = 1; i <= n; i++) { sum += i; } cout << sum << endl; return 0; }
while 语句
while 循环
while
循环只关注循环终止的条件和循环体的内容本身。while
语法:
while (循环成立条件) {
循环体
}
while
循环执行逻辑:- 只要循环成立条件为真,就进入循环体
- 重复这个步骤,直到循环成立条件为假
- 举例(猜数字)
// 声明生成的随机数字和猜的数字这两个变量
int num, guess;
// 提供随机种子
srand((unsigned)time(NULL));
// 随机生成一个1-100的数字
num = rand() % 100 + 1;
// 输入猜测的数字
cin >> guess;
// 如果猜的数字和生成的数字不相同就进入循环
while (guess != num) {
// 输出猜大了还是猜小了
if (guess > num)
cout << "猜大了" << endl;
else if (guess < num)
cout << "猜小了" << endl;
// 重新输入猜测的数字
cin >> guess;
}
// 当猜的数字和生成的数字相同时,跳出循环后,输出“猜对了”
cout << "猜对了" << endl;
do while 循环
- 无论如何,至少要执行一次猜数字的操作,可以用
do while
的写法
Tips:在刚刚的代码中,可以发现在循环体里有猜数字(cin >> guess
)的操作,在循环开始前也有猜数字的操作。这就适合用 do while
。
do while
语法
do {
循环体
} while (循环成立条件);
do while
执行逻辑- 和
while
类似 - 唯一的区别在于:因为条件表达式出现在循环的尾部,所以至少会执行一次循环体,执行完成后,再判断是否进入下一次循环。
- 和
举例
用do while
来写猜数字游戏的程序段:
// 声明生成的随机数字和猜的数字这两个变量
int num, guess;
// 提供随机种子
srand((unsigned)time(NULL));
// 随机生成一个1-100的数字
num = rand() % 100 + 1;
do {
// 输入猜测的数字
cin >> guess;
// 输出猜大了还是猜小了
if (guess > num)
cout << "猜大了" << endl;
else if (guess < num)
cout << "猜小了" << endl;
} while (guess != num);
// 当猜的数字和生成的数字相同时,跳出循环后,输出“猜对了”
cout << "猜对了" << endl;
练习
-
输入一个小于10000的整数,判断其是否为质数,若是则输出yes,否则输出no(请用while语法实现)
输入描述:
一行,一个正整数
输出描述:
一个字符串,yes或no
#include <bits/stdc++.h> using namespace std; int main() { // 请补全代码,实现题目功能 int num, i = 2; bool mark = false; cin >> num; if (num == 2) { cout << "yes" << endl; } else { while (i < num) { if (num % i) { i++; mark = true; } else { mark = false; break; } } if (mark) cout << "yes" << endl; else cout << "no" << endl; } return 0; }
多重循环
正如if
语句可以通过嵌套,实现分支内部的新分支,循环也是可以嵌套的。
- 循环嵌套适用于循环的大操作里有重复的小操作的情景。
- 举例:打印一个九九乘法表:
循环的大操作:对于1-9
,每个数字都打印一行 大操作中重复的小操作:在第i行里,对于每个小于等于i的数字j,都打印出i和j组成的乘法公式。
如果我们用for
循环内部嵌套for
循环的方式来写,代码是这样实现的:
// 1-9,每个数字打印一行
for (int i = 1; i <= 9; i++) {
// 在第i行中,对于每个小于i的数字,都打印一个等式和tab分隔
for (int j = 1; j <= i ; j++) {
cout << j << "*" << i << "=" << j*i << "\t";
}
// 第i行最后打印换行符
cout << endl;
}
如果我们用for
循环内部嵌套while
循环的方式来写,代码就是这样的:
// 1-9,每个数字打印一行
for (int i = 1; i <= 9; i++) {
// 在第i行中,对于每个小于i的数字,都打印一个等式和tab分隔
int j = 1;
while (j <= i) {
cout << j << "*" << i << "=" << j*i << "\t";
j++;
}
// 第i行最后打印换行符
cout << endl;
}
通过这个例子,我们一起来看看循环嵌套的注意事项:
- 可以任意嵌套,比如
for
嵌for
,for
嵌while
,while
嵌for
,while
嵌whil
e都可以 - 如果是
for
嵌for
,内外层的循环变量(比如上述代码的i和j)需要用不一样的变量,否则容易产生混乱 - 在嵌套操作中都需要使用缩进,以增强代码可读性
- 可以多层嵌套,但是有时候太多层嵌套容易超时,需要引起注意
练习
-
打印出n层高的*三角形
输入描述:
一行,一个整数n
输出描述:
从上向下数,第i层有i个星号,左对齐
#include <bits/stdc++.h> using namespace std; int main() { // 请补全代码,实现题目功能 int i, j, n; cin >> n; for (i = 1; i <= n; i++) { for (j = 1; j <= i; j++) { cout << '*'; } cout << endl; } return 0; }
-
小明钱包里装着各种纸币。纸币有4种(纸币的类型有1元、3元、5元和10元),每一种分别有a、b、c、d张。现在小明要出门买东西,他需要支付N元,在不找零的情况下,请问能支付成功吗?如果能成功支付,那么请计算出有多少种支付方式;如果不能成功支付,就输出no。
输入描述:
输入共 1 行,包含 5个整数 a、b、c、d、n,之间用一个空格隔开。abcd小于11
输出描述:
如果不能成功支付,则输出:no
如果可以成功支付,则输出:一个整数,表示支付方式的总数
#include <iostream> using namespace std; int main() { // 1,3,5,10的张数,以及总价,枚举时的支付价,支付 方式数量 int a, b, c, d, n, sum, num=0; cin >> a >> b >> c >> d >> n; for (int i=0; i<=d; i++) { if (i*10 > n) break; for (int j=0; j<=c; j++) { if ((i*10 + j*5) > n) break; for (int k=0; k<=b; k++) { if ((i*10 + j*5 + k*3) > n) break; for (int p=0; p<=a; p++) { sum = i*10 + j*5 + k*3 + p; if (sum == n) num += 1; else if (sum > n) break; } } } } if (num) cout << num << endl; else cout << "no" << endl; return 0; }
-
- A重数的循环
当一个n位数k的每一位都是同样的数字a时,我们把k称作a的n重数,例如666被称为6的三重数。
现在给定t(1≤ t ≤ 20)对a和n,求a的n重数k。
对于100%的数据满足1 ≤ k ≤ 10^11。
输入描述:
第一行一个整数t,
接下来t行,每行两个整数 a,n,中间1个空格间隔
输出描述:
输出共t行,每行一个整数 k
示例 1:
输入: 2 1 2 6 3 输出: 11 666
代码:
#include <iostream> using namespace std; int main() { int t, a, n; long long num; cin >> t; for (int i = 0; i < t; i++) { cin >> a >> n; num = a; for (int j=2; j<=n; j++) num = num * 10 + a; cout << num << endl; } return 0; }
- A重数的循环