循环结构

循环用于重复执行一段代码,直到条件不再满足。

自增与自减

i++ 和 i-- 是 C++ 中常用的运算符,用于让变量加 1 或减 1。

写法含义等价于
i++后置自增,先使用 i 的值,再让 i 加 1i = i + 1
++i前置自增,先让 i 加 1,再使用 i 的值i = i + 1
i--后置自减,先使用 i 的值,再让 i 减 1i = i - 1
--i前置自减,先让 i 减 1,再使用 i 的值i = i - 1

在循环中,通常只关心“加 1”或“减 1”,所以 i++ 和 ++i 的效果一样。

int i = 0;
i++;  // i 变成 1
i--;  // i 变成 0

for 循环

语法:

for (初始化; 条件; 更新) {
    // 循环体
}

执行顺序:

  1. 执行初始化(只执行一次)
  2. 判断条件,如果为真,执行循环体
  3. 执行更新
  4. 回到第 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 循环

语法:

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当前循环 / switch立即跳出当前循环,继续执行循环后面的代码
continue当前循环的本次迭代跳过本次剩余语句,进入下一次循环
return整个函数立即结束函数;在 main 中 return 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,或者使用浮点类型。

两种数列对比

数列首项公差 / 公比第 n 项循环中的更新
等差数列a1da1 + (n - 1) * da += d
等比数列a1qa1 * q^(n-1)a *= q

循环嵌套打印图像

利用循环嵌套,可以按行、按列输出字符,从而打印出各种图形。

打印实心矩形

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;
}

输出:

    *****
   *****
  *****
 *****
*****