程序员小张:“佛祖,我写for循环总是死循环,怎么办?”
佛祖:“放下键盘,立地成佛。”
小张:“可项目明天上线啊!”
佛祖:“……那你还是看看这篇文章吧。”
“佛如”循环,其实是for循环的谐音梗(毕竟写代码写到头秃时,只能求佛祖保佑了)。
它的标准写法长这样:
#include
int main()
{
int i; // 声明循环变量 i (代表次数)
for (i = 1; i <= 10; i++)
{ // 从1开始念到10
printf("南无阿弥陀佛 %d\n", i);
}
return 0;
}
翻译成人话:
初始化:老衲先给你个初始值(比如int i = 0)。
条件:只要条件为真(比如i < 10),就继续念经(执行循环)。
更新:每念完一次经,记得更新计数器(比如i++)。
光说不练假把式,走几个简单的例子,助你修成正果。
#include
int main()
{
int i; // 声明循环变量 i (代表次数)
for (i = 1; i <= 10; i++)
{ // 从1开始念到10
printf("南无阿弥陀佛 %d\n", i);
}
return 0;
}
#include
int main()
{
int lights[5]; // 声明5盏灯(数组)
int bulb; // 循环变量代表灯的位置
// 给每盏灯赋一个能量值(位置号*10)
for (bulb = 0; bulb < 5; bulb++)
{
lights[bulb] = bulb * 10; // bulb 从0开始是数组的标准操作!
}
// 展示一下开光效果
for (bulb = 0; bulb < 5; bulb++)
{
printf("灯%d的能量: %d\n", bulb, lights[bulb]);
}
return 0;
}
for循环虽好,坑也不少。一念之差,可能就从“优雅循环”变成“无限轮回”,让你CPU冒烟、程序卡死、头发脱落(大误)。请牢记以下避坑真言:
for (int i = 0; i < 5; i++)
printf("这句话在循环内\n"); // 你以为两句话都在循环?错!
printf("这句话也会执行5次?!?\n"); // 实际它并没有循环!因为没加大括号!
渡劫真言: **{ }!{ }!{ }!** 重要的事情说三遍!不管循环体里有一行还是十行,老老实实加上大括号!这能省去你99%的“佛祖都想不通为啥逻辑不对”的诡异BUG时间。上面的例子,只有加上大括号,第二句printf才会被重复执行。
for (int i = 0; i < 10; i++)
{
printf("%d ", i);
i += 2;
// 你偷偷改i?佛祖不按你套路出牌了!可能只循环几次就结束,也可能死循环?
}
渡劫真言: 除非你有极其特殊(且自圆其说)的需求,不要在循环体内部直接修改循环控制变量(i)! 让“每次轮回后的动作”(i++)去管理它!改了它,循环次数就可能失控,佛祖也保不了你!
for (float x = 0.0; x != 1.0; x += 0.1)
{ // 浮点数精度误差!可能永远 != 1.0!
printf("%f\n", x);
}
渡劫真言: 尽量避免用浮点数(float, double)做循环控制变量!浮点数的精度问题可能导致循环次数不精确甚至形成死循环。上面例子中,x可能最终等于0.999999...之类的值,永远不会精确等于1.0!如果必须用,考虑用整数计数器,然后在循环内部转换成浮点计算:
for (int count = 0; count < 10; count++)
{ // 精确循环10次
float x = count * 0.1;
printf("%f\n", x);
}
// 佛祖问:这是空寂(空语句)?还是等待轮回(死循环)?
for (int i = 0; i < 10; i++); // 注意这个要命的分号 ';'!!!
{
printf("这个打印只执行一次!\n"); // {}内的代码和循环无关了!
}
那个写在for圆括号后面的分号;,意味着循环体是一个空语句! printf所在的{}块,根本不是循环体的一部分!它只会在循环结束后(循环变量i已经变成10)执行一次。而循环自己默默地、飞快地、不干任何事地循环了10次。
渡劫真言: 不要在for (...)后面直接跟分号;! 除非你真的想要一个空循环(这种情况很少见,且需要有注释说明)。要让{紧跟在for (...)后面。
int array[5] = {1, 2, 3, 4, 5};
for (int i = 0; i <= 5; i++)
{ // i从0到5,越界了!
printf("%d ", array[i]); // 当i=5时访问了非法内存!程序崩溃或输出垃圾数据!
}
渡劫真言: C语言不会自动检查数组边界!牢记数组下标从0开始!如果数组大小是N(本例为5),那么有效的下标范围是0到N-1(0到4)。循环条件要用i < N(i < 5),千万不要用i <= N(i <= 5)! 这是导致崩溃和安全漏洞的常见元凶之一!当你打印或操作数组内容,务必确保你的i老老实实待在0到N-1的“佛国净土”之内。
等你掌握了基础“佛如”大法,就可以解锁更多姿势:
#include
#define ROWS 3
#define COLS 3
int main()
{
// 初始化两个矩阵
int matrix1[ROWS][COLS] = {{1,2,3},{4,5,6},{7,8,9}};
int matrix2[ROWS][COLS] = {{9,8,7},{6,5,4},{3,2,1}};
int result[ROWS][COLS] = {0};
// 嵌套循环实现矩阵加法
for (int i = 0; i < ROWS; i++)
{ // 行控制
for (int j = 0; j < COLS; j++)
{ // 列控制
result[i][j] = matrix1[i][j] + matrix2[i][j];
}
}
// 打印结果
printf("矩阵加法结果:\n");
for (int i = 0; i < ROWS; i++)
{
for (int j = 0; j < COLS; j++)
{
printf("%2d ", result[i][j]);
}
printf("\n"); // 换行打印新行
}
return 0;
}
#include
int main()
{
int arr[] = {10, 20, 30, 40, 50};
int length = sizeof(arr) / sizeof(arr[0]);
//局部变量作用域控制
for (int i = 0; i < length; i++)
{ // i仅在循环内有效
printf("正序[%d]: %d\n", i, arr[i]);
}
return 0;
}
#include
int main()
{
// 示例:隔一个取一个值 (i += 2)
printf("偶数索引元素:");
for (int i = 0; i < 10; i += 2)
{
printf("%d ", i);
}
// 示例:步长为3
printf("\n步长为3:");
for (int j = 0; j < 10; j += 3)
{
printf("%d ", j);
}
// 示例:负步长
printf("\n从10递减到0:");
for (int k = 10; k >= 0; k -= 2)
{
printf("%d ", k);
}
return 0;
}
#include
int main()
{
int validInputs[] = {5, 8, 12, 15, -1}; // -1作为终止标志
int secretNumber = 12;
// 复合条件:在有效范围内且未找到目标
for (int i = 0; i < 5 && validInputs[i] >= 0; i++)
{
printf("检查:%d\n", validInputs[i]);
if (validInputs[i] == secretNumber)
{
printf("找到目标数字 %d !\n", secretNumber);
break; // 提前终止循环
}
}
// 动态条件示例
printf("\n动态条件测试:\n");
int counter = 0;
for (int num = 100; num > 0 && counter < 3; num /= 2)
{
printf("%d ", num);
counter++;
}
return 0;
}
最后,送你一句终极编程心法:
清晰的逻辑 + 良好的习惯(用{}、防越界) = 稳健的“佛如”循环 = 内心平静的程序员!
当你写for循环时,心中默念:
初始化好了没有?
条件判断会不会掉坑(浮点数?边界?)?
更新动作会不会作死?
循环体有{}护体吗?
数组访问没越界吧?
如此这般,“佛如”之力与你同在!再也不用对着电脑屏幕大喊“佛如救救我吧!”了。
快去实践你的“佛如”大法吧!愿你早日修成正果,代码无BUG,需求不变更,头发永常在!
关注微信公众号「芯动视界」,解锁代码世界的核心奥秘!获取更多资料!
深耕C语言精髓:从指针迷宫到内存管理,系统化讲解,助你夯实底层基础。
⚡️ 探索嵌入式实战:剖析项目案例,分享避坑指南,让开发效率翻倍。
无论你是初无论你是初探嵌入式的新手,还是寻求进阶的老兵,这里都有你需要的硬核干货与技术洞见。一起用代码“芯”动视界!