C语言for循环嵌套实战:从逻辑到代码的六种经典应用
掌握C语言双层for循环的关键在于理清内外层控制变量的依赖关系。本文通过阶乘累加、字符金字塔、素数判定、乘法口诀表、冒泡排序及二维数组初始化等六个实战案例,详细拆解循环执行流程与代码实现,帮助初学者建立正确的嵌套逻辑思维。
理解嵌套循环的执行逻辑
C语言中,for循环嵌套指的是在一个for循环体内包含另一个完整的for循环结构。对于初学者而言,面对多层缩进的代码容易迷失执行顺序。最核心的学习策略是“剥离法”:暂时忽略外层循环的约束,先单独分析内层循环的执行条件;确认内层逻辑无误后,再结合外层循环变量看其如何驱动内层循环重复运行。
示例结构示意:
for (初始; 条件; 步进) { // 外层
for (初始; 条件; 步进) { // 内层
// 核心操作
}
}
这种由内而外的分析方式能显著降低认知负担,准确预判代码的运行结果。
第一题:阶乘累加求和
目标:计算 $1! + 2! + 3! + … + 10!$ 的值。
此题需要两层循环配合:外层循环控制当前计算的数字(从1到10),内层循环负责计算该数字的阶乘。需特别注意每次外层循环开始时,用于存储阶乘结果的变量必须重置为1。
#include <stdio.h>
int main()
{
int i = 0;
int j = 0;
int sum = 1; // 存储当前数字的阶乘
int ret = 0; // 存储总和
for (i = 1; i <= 10; i++)
{
sum = 1; // 【关键步骤】重置阶乘基数
for (j = 1; j <= i; j++)
{
sum *= j; // 计算 i! = i * (i-1)!
}
ret += sum; // 累加阶乘结果
}
printf("ret=%d\n", ret);
return 0;
}第二题:字符金字塔打印
目标:接收用户输入的字符,使用嵌套循环打印出金字塔形状的图案。
图案的每一行由两部分组成:前导空格和显示的字符。外层循环控制行数,内层循环分为两段:第一段打印空格以形成右对齐或居中效果,第二段打印目标字符并保留一个尾随空格以保持间距。
int main()
{
char ch = 0;
scanf("%c", &ch); // 输入目标字符
int i = 0;
int j = 0;
for (i = 0; i < 5; i++)
{
// 第一部分:打印空格
for (j = 0; j <= 5 - i; j++)
{
printf(" ");
}
// 第二部分:打印字符
for (j = 0; j <= i; j++)
{
printf("%c ", ch);
}
printf("\n"); // 每行结束换行
}
return 0;
}第三题:查找指定区间的素数
目标:找出 100 到 200 之间的所有素数并输出。
素数是只能被 1 和自身整除的大于1的自然数。判断逻辑采用试除法:用待查数字 $i$ 去除以从 2 开始的整数 $j$,若发现能整除则跳出内层循环;若内层循环完整执行完毕(即 $j$ 增长到等于 $i$),说明 $i$ 未被任何小于自身的数整除,则为素数。
// 题目三:打印100~200之间的素数
// 备注:素数是只能被1和其本身整除的数
int main()
{
int i = 0;
int j = 0;
for (i = 100; i <= 200; i++)
{
// 尝试因子 j
for (j = 2; j <= i - 1; j++)
{
if (i % j == 0)
break; // 找到一个因子,提前终止检查
}
// 如果 j 已经等于 i,说明没找到因子(除了1)
if (i == j)
printf("%d ", j); // 注意此处输出的是 j,因为 i==j
}
return 0;
}第四题:动态乘法口诀表
目标:根据用户输入的行数 $n$,打印对应的乘法口诀表部分。
利用 $i$ 作为行号,$j$ 作为列号,且满足 $j \le i$ 的条件打印 $i \times j$。使用格式占位符 %-2d 确保列宽固定为两位并对齐左端,保证表格整齐美观。
// 题目四:打印乘法口诀表
int main()
{
int n = 0;
scanf("%d", &n); // 读取行数
int i = 0;
int j = 0;
for (i = 1; i <= n; i++)
{
for (j = 1; j <= i; j++)
{
// %-2d 表示左对齐,占两格宽度
printf("%d*%d=%-2d ", i, j, i * j);
}
printf("\n");
}
return 0;
}第五题:冒泡排序算法实现
目标:对无序整型数组进行升序排列。
冒泡排序的核心思想是反复扫描相邻元素,若顺序错误则交换。外层循环 $i$ 控制需要进行比较的轮数(总共 $N-1$ 轮)。内层循环 $j$ 负责逐对比较相邻元素。由于每一轮结束后,最大的元素会像气泡一样沉底,因此内层比较的范围可以随着 $i$ 的增加而减小(排除已排好的末尾元素)。
// 题目五:冒泡排序
// 备注:将无序的数组按顺序排列
int main()
{
int arr[] = { 2,4,6,8,10,1,3,5,7,9 };
// 计算数组长度
int sz = sizeof(arr) / sizeof(arr[0]);
int i = 0;
int j = 0;
for (i = 0; i < sz - 1; i++) // 控制趟数
{
for (j = 0; j < sz - 1 - i; j++) // 控制每趟的比较次数,越往后范围越小
{
if (arr[j] > arr[j + 1]) // 逆序则交换
{
int tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;
}
}
}
// 打印结果(原示例仅打印前5个,此处演示输出全部)
for (i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
return 0;
}第六题:二三维游戏棋盘初始化
目标:定义宏常量控制棋盘大小,使用嵌套循环初始化并打印 3x3 的游戏棋盘。
这是一个典型的二维矩阵处理问题。首先需要通过两个循环将所有位置填充为空格 ' '。随后,再次通过循环遍历每个坐标 $(i, j)$:打印格子内容,若非该行最后一个格子则打印分隔符 “|”。打印完一整行后,需要根据逻辑判断是否打印行分割线 “---|---|---”。
// 题目六:打印三子棋的棋盘
// | |
// ---|---|---
// | |
// ---|---|---
// | |
#define ROW 3
#define COL 3
int main()
{
char board[ROW][COL] = { 0 };
int i = 0;
int j = 0;
// 第一步:初始化棋盘数据
for (i = 0; i < ROW; i++)
{
for (j = 0; j < COL; j++)
{
board[i][j] = ' ';
}
}
// 第二步:绘制棋盘界面
for (i = 0; i < ROW; i++)
{
// 绘制行内容
for (j = 0; j < COL; j++)
{
printf(" %c ", board[i][j]);
if (j < COL-1)
{
printf("|"); // 非末列画竖线
}
}
printf("\n");
// 绘制行分割线(最后一行不需要分割线)
if (i < ROW-1)
{
for (j = 0; j < COL; j++)
{
printf("---");
if (j < COL-1)
{
printf("|");
}
}
printf("\n");
}
}
return 0;
}免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









