1) 表达式1、表达式2和表达式3之间是用分号
;
隔开的,千万不要写成逗号。
2)
for(表达式1;表达式2;表达式3)
的后面千万不要加分号,很多新手都会犯这种错误——会情不自禁地在后面加分号。
因为 for 循环只能控制到其后的一条语句,而在C语言中分号也是一个语句——空语句。所以如果在后面加个分号,那么 for 循环就只能控制到这个分号,下面大括号里面的语句就不属于 for 循环了。
下面来看看它的执行过程:
求解表达式1。
求解表达式2。若其值为真,则执行 for 语句中指定的内嵌语句,然后执行第3步;若表达式2值为假,则结束循环,转到第5步。
求解表达式3。
转回上面第2步继续执行。
循环结束,执行 for 语句下面的语句。
从这个执行过程中可以看出,“表达式1”只执行一次,循环是在“表达式2”“表达式3”和“内嵌语句”之间进行的。
for语句最简单的形式是:
for (循环变量赋初值; 循环条件; 循环变量增值)
下面给大家写一个程序,求 1+2+3+4+…+100 的总和。
# include <stdio.h>
int main(void)
int i;
int sum = 0; //sum的英文意思是“总和”
for (i=1; i<=100; ++i) //++是自加的意思, ++i相当于i = i + 1
sum = sum + i; /*等价于sum += i;但是不建议这么写, 因为sum = sum + i看起来更清楚、更舒服*/
printf("sum = %d\n", sum);
return 0;
输出结果是:
sum = 5050
这个程序的功能是实现求 1+2+3+4+…+100 的和,如果不用循环,加一次就要一条语句,加 100 次就要 100 条语句。这里是从 1 加到 100,要是从 1 加到 10000 那就要 10000 条语句。但有了循环就很方便了,你想加到多少就加到多少,只要改一个参数就可以了。所以循环很重要。
下面按照执行过程看看上面这个程序是怎样执行的。
1) 首先定义一个循环变量 i。定义的时候可以不给它赋初值,在 for 循环里面再给它赋初值也行。但前面说过,最好在定义变量的时候就对它进行初始化,如果值不确定就初始化为 0。所以程序中也可以在定义 i 的时候就给它赋初值,那么 for 循环里的“表达式1”就可以省略了,但分号不可以省略。
这样的话,执行的时候就跳过第1步,直接进入第2步,其他的不变。所以程序也可以像下面这样写:
# include <stdio.h>
int main(void)
int i = 1;
int sum = 0;
for (; i<=100; ++i)
sum = sum + i;
printf("sum = %d\n", sum);
return 0;
当然表达式1加上也行,大不了再重新赋一次值。
2) 然后定义一个用来存放“和”的变量 sum,并给它赋初值 0,然后进入 for 循环:
首先求解表达式1,即给变量i赋初值,
i=1;
表达式1只执行这一次,下面都不会再执行了。
然后求解表达式2,若 1<=100 成立,则执行 for 循环中的内嵌语句,即 sum=0+1。
然后执行第3步,变量 i 自加 1,即变量 i 由 1 变为 2。
然后再求解表达式2,2<=100 成立,则执行 for 循环中的内嵌语句,sum=0+1+2。
然后再执行第3步,变量 i 自加 1,即变量 i 由 2 变为 3。
然后再求解表达式2,即 3<=100 成立,则执行 for 循环中的内嵌语句,sum=0+1+2+3。
就这样一直循环下去,直到 ++i 等于 100 的时候,求解表达式2,即 100<=100 成立,则执行 for 循环中的内嵌语句,sum=0+1+2+3+…+100。
然后再执行第3步,变量 i 自加 1,即变量 i 由 100 变为 101。然后再求解表达式2,即 101<=100 不成立,则结束循环,执行 for 循环下面的语句即 printf。
以上就是这个程序的执行过程。关于 for 语句的代码规范化问题,有两点要再跟大家强调一下:
1)if、else、for、while、do 都只能控制到其后的一条语句,如果要控制多条语句必须加大括号
{}
。但基于代码规范化,if、else、for、while、do 后面的执行语句不论有多少行,就算只有一行也要加
{}
。
2) 像 if、for、while 等关键字之后应留一个空格再跟左括号
(
,以突出关键字。
此外上面的程序还有一个知识点要跟大家说一下:从功能上讲,
for(i=1; i<=100;++i)
完全可以写成
for(i=1; i<101; ++i)
,而且建议大家尽量使用这种写法。也就是说,循环语句的循环条件尽量写成半开半闭的,不管是 for 循环还是 while 循环。
for(i=1; i<101; ++i)
实际上是 1≤i<101,是半开半闭的;而
for(i=1; i<=100; ++i)
实际上是 1≤i≤100,是全闭的。那么为什么建议使用半开半闭的呢?因为如果写成 i<=100 的话,那么每次判断的时候都要判断两次,即 i<100 和 i==100,而写成 i<101 的话每次只需要判断一次。
也许有人说:程序在执行 i<=100 的时候不是将它转换成 i<100||i==100 吗?这样由“短路或”的知识可知,如果前面的为真那么后面的不就不会执行了吗?这样不也是判断一次吗?不是这样的,系统是不会将 i<=100 转换成 i<100||i==100 的,每次判断的时候 i<100 和 i==100 都要判断。
但是写成半开半闭也有一个问题,就是会影响对代码的理解。有时候写成全闭的区间理解起来才顺畅,而写成半开半闭反而不易理解,比如
<=
右边是变量或表达式的时候。这时候要以可读性为第一要素,即哪种好理解就使用哪种。现在 CPU 速度那么快,也不在乎那点效率。所以前面说“尽量”,没有要求一定要那样写。
下面再给大家写一个程序,求 1 到 100 之间所有奇数的和。
# include <stdio.h>
int main(void)
int i;
int sum = 0 ;
for (i=1; i<100; i+=2) //i+=2;等价于i = i + 2;
sum = sum + i;
printf("sum = %d\n", sum);
return 0;
输出结果是:
sum = 2500
关于自增和自减
一直以来,++ 和 –– 语法浪费了太多人的时间。说句实在话,++ 和 –– 在C语言中根本就不重要,除了表达简练外,真的没有什么其他好处了。
简单地说:++i 和 i++ 在单独使用时,都表示 i=i+1;––i 和 i–– 在单独使用时,都表示 i=i–1。
而 a=++i 就相当于 i=i+1,a=i;a=i++ 就相当于 a=i,i=i+1。
同理,a=––i 就相当于 i=i–1,a=i;a=i–– 就相当于 a=i,i=i–1。
如果实在搞不明白 ++ 和 –– 是怎么回事,那也不是什么天塌下来的事情。因为
a=++i;
完全可以写成
i++; a=i;
。而
a=i++;
也完全可以写成
a=i; i++;
。而且,这也是一种很好的程序风格。
作为一个优秀的程序员,在你的程序中就不应该体现出 ++i 和 i++ 的区别,要么都用 ++i,要么都用 i++,不要一会儿用 ++i 一会儿用 i++。
对于自增和自减还有一点需要强调的是:只有“变量”才能进行自增和自减!你认为 3++ 等于多少?C语言中没有这种写法,常量是不能进行自增和自减的。
for循环练习
1) 求 1! + 2! + 3! + ... + n!
# include <stdio.h>
int main(void)
int n = 0;
int i = 0;
int m = 1;
int sum=0;
printf("请输入n的值:");
scanf("%d", &n);
for (i=1; i<=n; ++i)
m = m * i;
sum = sum +m;
printf ("sum = %d\n", sum);
return 0;
这个程序虽然短,但逻辑性很强,算法很好,所以建议读者记住。因为逻辑性强,所以只看是很难明白的,自己在纸上试一下,将自己当成计算机一步步地计算就明白了。
假如 n=4:
当 i=1 时,m=1,sum=1。
当 i=2 时,m=1×2,sum=1+1×2。
当 i=3 时,m=1×2×3,sum=1+1×2+1×2×3。
当 i=4 时,m=1×2×3×4,sum=1+1×2+1×2×3+1×2×3×4。
看出规律来了吗?m 的值是一直往下乘,乘以 i 之前 m 的值是(i–1)的阶乘,乘以 i 之后 m 的值就是 i 的阶乘了。这样 i 循环到多少,m*i 就立刻将这个数的阶乘计算出来,然后加到 sum 中。
2) for 和 if 的嵌套使用。求 1 到 100 之间所有能被 3 整除的数之和。
# include <stdio.h>
int main(void)
int i;
int sum = 0;
for (i=3; i<100; ++i)
if (0 == i%3)
sum = sum +i;
printf("sum = %d\n", sum);
return 0;
输出结果是:
sum = 1683
大家想想如果不用 if,这个程序能不能写出来?当然能,能被 3 整除的数肯定是 3 的倍数,只要 i 每次自加 3 就行了。我们将这个程序写一下:
# include <stdio.h>
int main(void)
int i;
int sum = 0;
for (i=3; i<100; i+=3)
sum = sum +i;
printf("sum = %d\n", sum);
return 0;
因为 ++i 每次只加 1,而 i+=3 每次加 3,所以这种写法与第一种写法比较起来计算机少执行很多步,所以执行起来更快。由此可知,完成相同的功能,算法不一样则效果就不一样。对计算机而言当然是执行得越快越好。
3) 编写程序,输出 1~1000 之间所有的完全平方数。
# include <stdio.h>
# include <math.h> //要用sqrt()
int main(void)
int i; //循环变量
int x; //存储每个数的二次方根
for (i=1; i<1000; ++i)
x = sqrt(i); /*如果i不是完全平方数, 那么sqrt(i)肯定是小数, 而i是int型, 所以x是sqrt(i)取整后的值, 这样x*x肯定不等于i*/
if (x*x == i)
printf("%d\t", i); // \t是跳到下一个Tab位置
printf("\n");
return 0;
输出结果是:
1 4 9 16 25 36 49 64 81 100
121 144 169 196 225 256 289 324 361 400
441 484 529 576 625 676 729 784 841 900
其实这个程序还有更简单的算法,不需要使用 sqrt()。下面将这个程序也写下来:
# include <stdio.h>
int main(void)
int i; //循环变量
for (i=1; i*i<1000; ++i)
printf("%d\t", i * i); // \t是跳到下一个Tab位置
printf("\n");
return 0;
输出结果是:
1 4 9 16 25 36 49 64 81 100
121 144 169 196 225 256 289 324 361 400
441 484 529 576 625 676 729 784 841 900
关注公众号「
站长严长生
」,在手机上阅读所有教程,随时随地都能学习。本公众号由
C语言中文网站长
亲自运营,长期更新,坚持原创。
微信扫码关注公众号
一套完整的嵌入式开发学习路线(高薪就业版)
一套课程卖1万,TMD太贵了!
跑了3000公里,见了一位大佬
计算机二级证书到底有没有用?需要报考吗?
Java可以做什么?9种Java实际用途汇总
大学生不要为了赚钱而兼职,没有什么卵用!
曝光一下字节跳动的工资待遇和职位级别
C/C++学习路线之Windows软件开发(非常详细)
大白话聊栈溢出(stack overflow)
人工智能、机器学习、深度学习的区别,终于说清楚了