C 语言 for 循环语句的一般形式为:
一般情况下,初始化总是一个赋值语句,它用来为循环控制变量赋初值;条件表达式则是一个关系表达式,它决定什么时候退出循环;而增量定义循环控制变量每循环一次后按什么方式变化。这三个部分之间用分号“;”分割开来。
从功能上看,虽然半开半闭区间写法和闭区间写法的功能是完全相同的,但相比之下,半开半闭区间写法更能够直观地表达意思,具有更高的可读性。下面,我们就通过示例代码看看两者之间的区别。
其中,闭区间的写法示例如下面的代码所示:
for(i=0;i<=n-1;i++)
{
/*处理代码*/
}
在上面的代码中,i 值属于闭区间写法。
半开半闭区间的写法示例如下面的代码所示:
for(i=0;i<n;i++)
{
/*处理代码*/
}
在上面的代码中,i 值属于半开半闭区间写法,即“0=<i<n”,起点到终点的间隔为 n,循环次数为 n。
从上面的两段示例代码中可以看出,尽管它们的功能是完全相同的,但相比之下,第二个程序示例(半开半闭区间写法)具有更高的可读性。因此,在 for 循环中,我们应该尽量使循环控制变量的取值采用半开半闭区间写法。
我们知道,for 循环随着循环次数的增加,会加大对系统资源的消耗。如果你写的一个循环体内的代码相当耗费资源,或者代码行数众多(一般来说循环体内的代码不要超过 20 行),甚至超过一显示屏,那么这样的程序不仅可读性不高,而且还会让你的程序的运行效率大大降低。这个时候,我们通常可以通过如下两种方法进行优化。
1) 重新设计这个循环,确认这些操作是否都必须放在这个循环里,并仔细考虑循环体内的语句是否可以放在循环体之外,从而使循环体内工作量最小化,提高程序的时间效率。如下面的示例代码所示:
for (i = 0;i < n;i++)
{
tmp += i;
sum = tmp;
}
很显然,在上面的代码中每执行一次 for 循环,就要执行一次“sum=tmp”语句来重新为变量 sum 进行赋值,这样的写法很浪费资源。因此,我们完全可以将“sum=tmp”语句放在 for 语句之后,如下面的示例代码所示:
for (i = 0;i < n;i++)
{
tmp += i;
}
sum = tmp;
这样,“sum=tmp”语句只执行一次,不仅可以提高程序执行效率,而且程序也具有更高的可读性。
2) 可以考虑将这些代码改写成一个子函数,在循环中只调用这个子函数即可。
在 for 循环语句中,我们应该严格避免在循环体内修改循环变量,否则很有可能导致循环失去控制,从而使程序执行违背我们的原意,如下面的示例代码所示:
for(i=0;i<10;i++)
{
i=10;
}
在上面的代码中,在循环体内对循环变量i进行赋值之后,for 循环中止执行,从而使程序执行违背我们的原意,更严重的情况会给程序带来灾难性的后果。
一般情况下,我们应该尽量避免在程序的循环体内包含逻辑判断语句。当循环体内不得已而存在逻辑判断语句,并且循环次数很大时,我们应该尽量想办法将逻辑判断语句移到循环语句的外层,从而使程序减少执行逻辑判断语句的次数,提高程序的执行效率。如下面的示例代码所示:
for (i = 0;i < n;i++)
{
if (condition)
{
DoSomething();
}
else
{
DoOtherthing();
}
}
在上面的代码中,每执行一次 for 循环,都要执行一次 if 语句判断。当 for 循环的次数很大时,执行多余的判断不仅会消耗系统的资源,而且会打断循环“流水线”作业,使得编译器不能对循环进行优化处理,降低程序的执行效率。因此,我们可以通过将逻辑判断语句移到循环语句的外层的方法来减少判断的次数,如下面的代码所示:
if (condition)
{
for (i = 0;i < n;i++)
{
DoSomething();
}
}
else
{
for (i = 0;i < n;i++)
{
DoOtherthing();
}
}
虽然上面的代码没有前面的看起来简洁,但却使程序执行逻辑判断语句减少 n-1 次,在 for 循环次数很大时,这种优化显然是值得的。
最后还需要注意的是,循环体中的判断语句是否可以移到循环体外,要视程序的具体情况而定。一般情况下,与循环变量无关的判断语句可以移到循环体外,而有关的则不可以。
尽量将多重循环中最长的循环放在最内层,最短的循环放在最外层
在多重 for 循环中,如果有可能,应当尽量将最长的循环放在最内层,最短的循环放在最外层,以减少 CPU 跨切循环层的次数。如下面的示例代码所示:
for (i=0;i<100;i++)
{
for (j=0;j<5;j++)
{
/*处理代码*/
}
}
为了提高上面代码的执行效率,我们可以依照这条建议将上面的代码修改为如下形式:
for (j=0;j<5;j++)
{
for (i=0;i<100;i++)
{
/*处理代码*/
}
}
这样,既不会失去程序原有的可读性,同时也提高了程序的执行效率。
有研究数据表明,当循环嵌套超过 3 层,程序员对循环的理解能力会极大地降低。同时,这样程序的执行效率也会很低。因此,如果代码循环嵌套超过 3 层,建议重新设计循环或将循环内的代码改写成一个子函数。