循环结构
循环用于重复执行一段代码,直到条件不再满足。
自增与自减
i++ 和 i-- 是 C++ 中常用的运算符,用于让变量加 1 或减 1。
在循环中,通常只关心“加 1”或“减 1”,所以 i++ 和 ++i 的效果一样。
int i = 0;
i++; // i 变成 1
i--; // i 变成 0
for 循环
语法:
for (初始化; 条件; 更新) {
// 循环体
}
执行顺序:
- 执行初始化(只执行一次)
- 判断条件,如果为真,执行循环体
- 执行更新
- 回到第 2 步,直到条件为假
示例:输出 1 到 5
for (int i = 1; i <= 5; i++) {
cout << i << " ";
}
// 输出:1 2 3 4 5
示例:倒序输出 5 到 1
for (int i = 5; i >= 1; i--) {
cout << i << " ";
}
// 输出:5 4 3 2 1
while 循环
语法:
只要条件为真,就重复执行循环体。条件在每次循环前判断。
示例:输出 1 到 5
int i = 1;
while (i <= 5) {
cout << i << " ";
i++;
}
// 输出:1 2 3 4 5
注意: 循环体内一定要有让条件趋向于假的语句,否则会变成死循环。
do-while 循环(拓展)
语法:
do {
// 循环体
} while (条件);
特点: 先执行一次循环体,再判断条件。至少执行一次。
示例:
int i = 1;
do {
cout << i << " ";
i++;
} while (i <= 5);
// 输出:1 2 3 4 5
for 和 while 的选择
- 知道循环次数:用
for 更方便。
- 只知道循环条件:用
while 更方便。
- 两者可以互相转换。
循环嵌套
循环里面还可以再写循环,称为循环嵌套。
for (int i = 1; i <= 3; i++) {
for (int j = 1; j <= 3; j++) {
cout << i << "," << j << " ";
}
cout << endl;
}
输出:
1,1 1,2 1,3
2,1 2,2 2,3
3,1 3,2 3,3
循环终止
在循环中,除了让循环条件自然变为假,还可以使用 break、continue、return 主动控制循环。
break
作用:立即结束当前所在的整个循环,跳出循环体,继续执行循环后面的代码。
for (int i = 1; i <= 10; i++) {
if (i == 5) break;
cout << i << " ";
}
// 输出:1 2 3 4
注意:break 只跳出最内层循环。如果是嵌套循环,它只会结束它所在的那一层。
continue
作用:跳过本次循环中 continue 后面的语句,直接进入下一次循环。
for (int i = 1; i <= 10; i++) {
if (i % 2 == 0) continue;
cout << i << " ";
}
// 输出:1 3 5 7 9
注意:在 while 循环中使用 continue 时,要确保循环变量仍然会被更新,否则可能造成死循环。
int i = 1;
while (i <= 5) {
if (i == 3) {
i++; // 必须更新,否则 i 永远为 3
continue;
}
cout << i << " ";
i++;
}
return
作用:从当前函数返回。在 main 函数中,return 0; 表示程序正常结束。
注意:return 会直接结束整个函数,而不只是跳出循环。如果在循环中执行 return,循环和函数都会立即结束。
int main() {
for (int i = 1; i <= 10; i++) {
if (i == 5) return 0; // 程序直接结束
cout << i << " ";
}
cout << "这行不会执行";
return 0;
}
// 输出:1 2 3 4
return 也可以返回其他值,但 main 函数通常返回 0 表示成功。
三者对比
常见错误
- 把
break 写在 if 里,以为只跳出 if,实际跳出整个循环。
- 在
while 中使用 continue 时忘记更新循环变量,导致死循环。
- 把
return 0; 写在循环里,以为只是结束循环,实际会结束整个程序。
- 混淆
break 和 continue:break 是彻底跳出循环,continue 只是跳过本次。
- 在
for 循环的更新部分误用 continue,可能跳过变量更新。
循环应用:等差数列与等比数列
等差数列
等差数列:从第二项起,每一项与前一项的差都等于同一个常数,这个常数叫做公差,通常用 d 表示。
- 首项:
a1
- 公差:
d
- 第 n 项:
an = a1 + (n - 1) * d
- 前 n 项和:
Sn = n * (a1 + an) / 2
用 for 循环输出等差数列的前 n 项:
int a1 = 1, d = 2, n = 5;
for (int i = 0; i < n; i++) {
cout << a1 + i * d << " ";
}
// 输出:1 3 5 7 9
用循环求等差数列前 n 项和:
int a1 = 1, d = 2, n = 5;
int sum = 0;
for (int i = 0; i < n; i++) {
sum += a1 + i * d;
}
cout << sum; // 输出:25
也可以用一个变量表示当前项,每次循环加上公差:
int a = 1, d = 2, n = 5;
for (int i = 0; i < n; i++) {
cout << a << " ";
a += d; // 下一项
}
// 输出:1 3 5 7 9
等比数列
等比数列:从第二项起,每一项与前一项的比都等于同一个常数,这个常数叫做公比,通常用 q 表示。
- 首项:
a1
- 公比:
q
- 第 n 项:
an = a1 * q^(n-1)
- 前 n 项和:
- 当
q != 1 时:Sn = a1 * (1 - q^n) / (1 - q)
- 当
q == 1 时:Sn = n * a1
用 for 循环输出等比数列的前 n 项:
int a1 = 2, q = 3, n = 4;
int a = a1;
for (int i = 0; i < n; i++) {
cout << a << " ";
a *= q; // 下一项
}
// 输出:2 6 18 54
用循环求等比数列前 n 项和:
int a1 = 2, q = 3, n = 4;
int sum = 0;
int a = a1;
for (int i = 0; i < n; i++) {
sum += a;
a *= q;
}
cout << sum; // 输出:80
注意: 等比数列增长非常快,容易超出 int 范围。如果需要计算较大项,应改用 long long,或者使用浮点类型。
两种数列对比
循环嵌套打印图像
利用循环嵌套,可以按行、按列输出字符,从而打印出各种图形。
打印实心矩形
int n = 4, m = 6; // 4 行 6 列
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
cout << "*";
}
cout << endl;
}
输出:
******
******
******
******
打印空心矩形
int n = 4, m = 6;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (i == 0 || i == n - 1 || j == 0 || j == m - 1)
cout << "*";
else
cout << " ";
}
cout << endl;
}
输出:
打印左对齐直角三角形
int n = 5;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= i; j++) {
cout << "*";
}
cout << endl;
}
输出:
打印右对齐直角三角形
int n = 5;
for (int i = 1; i <= n; i++) {
// 先打印空格
for (int j = 1; j <= n - i; j++) {
cout << " ";
}
// 再打印星号
for (int j = 1; j <= i; j++) {
cout << "*";
}
cout << endl;
}
输出:
打印等腰三角形(金字塔)
int n = 5;
for (int i = 1; i <= n; i++) {
// 打印空格
for (int j = 1; j <= n - i; j++) {
cout << " ";
}
// 打印星号,数量为 2 * i - 1
for (int j = 1; j <= 2 * i - 1; j++) {
cout << "*";
}
cout << endl;
}
输出:
*
***
*****
*******
*********
打印倒等腰三角形
int n = 5;
for (int i = n; i >= 1; i--) {
for (int j = 1; j <= n - i; j++) {
cout << " ";
}
for (int j = 1; j <= 2 * i - 1; j++) {
cout << "*";
}
cout << endl;
}
输出:
*********
*******
*****
***
*
打印菱形
菱形可以看作上半部分等腰三角形 + 下半部分倒等腰三角形。
int n = 4; // 上半部分行数
// 上半部分
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n - i; j++) cout << " ";
for (int j = 1; j <= 2 * i - 1; j++) cout << "*";
cout << endl;
}
// 下半部分
for (int i = n - 1; i >= 1; i--) {
for (int j = 1; j <= n - i; j++) cout << " ";
for (int j = 1; j <= 2 * i - 1; j++) cout << "*";
cout << endl;
}
输出:
*
***
*****
*******
*****
***
*
打印九九乘法表
for (int i = 1; i <= 9; i++) {
for (int j = 1; j <= i; j++) {
cout << j << "*" << i << "=" << i * j << "\t";
}
cout << endl;
}
输出(部分):
1*1=1
1*2=2 2*2=4
1*3=3 2*3=6 3*3=9
...
打印数字三角形
int n = 5;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= i; j++) {
cout << j << " ";
}
cout << endl;
}
输出:
1
1 2
1 2 3
1 2 3 4
1 2 3 4 5
打印平行四边形
int n = 5;
for (int i = 1; i <= n; i++) {
// 打印空格
for (int j = 1; j <= n - i; j++) {
cout << " ";
}
// 打印星号
for (int j = 1; j <= n; j++) {
cout << "*";
}
cout << endl;
}
输出:
*****
*****
*****
*****
*****