欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

【C语言】"for" "while" "do……while"

程序员文章站 2022-06-24 15:43:14
...

  在C语言中有三种循环语句:for语句,while语句以及do……while语句。
  首先,我们来看相比其他两种更为灵活的for语句。
  *for语句*
  一般形式:for(表达式1;表达式2;表达式3)
        循环语句
  其中三个表达式,作用不尽相同:
  表达式1:设置初始条件,只执行一次。可以为一个或多个变量设置初值(可以是与循环变量无关的其他表达式)。
  表达式2:循环条件表达式,用以判断循环是否继续。在每次执行循环体前先执行该表达式,决定是否继续执行循环。
  表达式3:用于循环条件的调整,例如使循环变量增值(也可以是与循环变量无关的其他表达式)。它是在执行完循环体后执行的。
  则可得到:for(循环变量赋初值;循环条件;循环变量增值)
        循环语句
  举个简单例子:在屏幕上输出数字1~10。
  代码如下:

#include<stdio.h>
#include<stdlib.h>
int main()
{
    int i = 0;
    for (i = 1; i <= 10; i++)
    {
        printf("%d ", i);
    }
    system("pause");
    return 0;
}

  输出结果:
  【C语言】"for" "while" "do……while"
  注意:
  ⑴不可在for 循环体内修改循环变量,以防止 for 循环失去控制。
  ⑵建议在for语句的循环控制变量的取值采用“半开半闭区间”写法。如下:

int i = 0;
for (i = 0; i<10; i++)
{}

  for循环语句的执行过程如下:
  【C语言】"for" "while" "do……while"
  其中,break和continue语句用以实现提前结束循环。
  break
  作用:使流程跳到循环体外,接着执行循环体下面的语句。
  但是break语句只能用于循环语句和switch语句之中,而不能单独使用。
  程序举例:

#include<stdio.h>
#include<stdlib.h>
int main()
{
    int i = 0;
    for (i = 1; i <= 10; i++)
    {
        if (i == 5)
            break;
        printf("%d ", i);
    }
    system("pause");
    return 0;
}

  输出结果:
  【C语言】"for" "while" "do……while"
  分析:进入for循环,i=1,表达式2结果为真,进入循环体进行判断:如果i等于5,则执行break语句,否则输出i。此后,i每次自增1,直到i等于5时,if语句中的表达式为真,则执行break语句,直接跳出for循环(此时不再输出i)。
  continue
  作用:只结束本次循环,即跳过循环体中下面尚未执行的语句,转到循环体结束点之前,接着执行for语句中的表达式3,然后进行下一次是否执行循环的判定。
  还是上面的例子,如果把其中的break换成continue:

#include<stdio.h>
#include<stdlib.h>
int main()
{
    int i = 0;
    for (i = 1; i <= 10; i++)
    {
        if (i == 5)
            continue;
        printf("%d ", i);
    }
    system("pause");
    return 0;
}

  输出结果:
  【C语言】"for" "while" "do……while"
  我们可以看到,输出结果中只有5没输出。
  分析:进入for循环,i=1,表达式2结果为真,进入循环体进行判断:如果i等于5,则执行continue语句,否则输出i(前4次循环输出1~4)。当i等于5时,执行continue语句,从而跳出此次循环(不输出5),进入下一次循环,此后i均不等于5,所以输出6~10。
  我们说过,for语句的较其他循环语句更为灵活,且功能强大:
  ⑴for语句中表达式1可以省略,即不对循环变量设初值(但是为了使循环可以正常执行,在for语句之前应给循环变量赋初值),但其后的分号(;)不能省略。如:

int i = 0;
for (; i<10; i++)

  ⑵for语句中表达式2也可以省略,即不设置和检查循环的条件。但是这样,循环会无终止地进行下去,循环变量的值不断增大。
  ⑶for语句中表达式3也可以省略,但程序设计者应在循环体内使循环变量增值以保证循环可以正常结束。如:

for (i = 0; i < 10; i++)
{
    //…
    i++;
    //…
}

  ⑷当然,for语句中的三个表达式可以同时省略,即不设初值,不判断条件,循环变量不增值。如:

for (; ;)
printf("%d ", i);

这样的循环会无终止地进行下去,显然没有什么实用价值。
  ⑸表达式1和表达式3可以是一个简单表达式,也可以是逗号表达式,如:

for (i = 1, j = 10; i <= j;i++,j--)

其中:表达式1为“i = 1, j = 10”,表达式3为“i++,j–”。在逗号表达式中应按自左至右的顺序依次求解每个表达式,整个逗号表达式的值为最右边的表达式的值。
  ⑹表达式2一半为关系表达式或逻辑表达式,也可以是数值表达式或字符表达式,只要其值为真(非0)就执行循环体。
  ⑺for语句的循环体可以为空,把原本在循环体内执行的语句放在表达式3中,且作用是一样的。
  ⑻C99允许在表达式1中定义变量并赋初值。如:

for (int i = 1; i <= 10; i++)

但要特别注意的是:表达式1中定义的变量只能在for语句的循环体内使用,不可在循环外使用。
--------------------------------
  *while语句*
  一般形式: while(表达式)
         循环语句
  说明:
  ⑴表达式称为循环条件表达式,当此表达式的值为真,就执行循环语句,否则不执行。
  ⑵语句即为循环体,循环体只能是一个语句,可以是一个简单的语句,也可以是用花括号括起来的复合语句。
  同样的例子,也可以用while循环来实现:在屏幕上输出数字1~10,代码如下:

#include<stdio.h>
#include<stdlib.h>
int main()
{
    int i = 1;
    while (i <= 10)
    {
        printf("%d ", i);
        i+=1;
    }
    system("pause");
    return 0;
}

  输出结果:
  【C语言】"for" "while" "do……while"
  注意:while循环的特点是:先判断条件表达式,后执行循环体语句。
  while循环语句的执行过程如下:
  【C语言】"for" "while" "do……while"
  在while循环中也可以使用break和continue语句来达到提前结束循环的目的,而且和在for循环中的意义是一样的,但是还是存在一些差异。
  break
  作用:在while循环中,只要遇到break,就停止后期的所有的循环。所以,while循环中的break是用于永久终止循环的。
  程序举例:

#include<stdio.h>
#include<stdlib.h>
int main()
{
    int i = 1;
    while (i <= 10)
    {
        if (i == 5)
            break;
        printf("%d ", i);
        i = i + 1;
    }
    system("pause");
    return 0;
}

  输出结果:
  【C语言】"for" "while" "do……while"
  分析:i=1,进入while循环,表达式结果为真,进入循环体进行判断:如果i等于5,则执行break语句,否则输出i,并且让i自增1,然后进入第二次循环……当i等于4时,if语句中的表达式为假,则输出4,然后i自增至5,此时if语句中的表达式为真,则执行break语句,直接终止while循环(此时不再输出i)。
  continue
  作用:while循环中,continue是用于终止本次循环的,也就是在本次循环中continue后边的代码不会再执行,而直接跳转到while语句的判断部分,进行下一次循环的入口判断。
  程序举例1:

#include<stdio.h>
#include<stdlib.h>
int main()
{
    int i = 1;
    while (i <= 10)
    {
        if (i == 5)
            continue;
        printf("%d ", i);
        i = i + 1;
    }
    system("pause");
    return 0;
}

  输出结果:
  【C语言】"for" "while" "do……while"
  可以发现,在4的后面没有出现“请按任意键继续…”。
  分析:i=1,进入while循环,表达式结果为真,进入循环体进行判断:如果i等于5,则执行continue语句,否则输出i,并且让i自增1,然后进入第二次循环……当i等于4时,if语句中的表达式为假,则输出4,然后i自增至5,此时if语句中的表达式为真,则执行continue语句,终止本次循环,准备进入下一次循环。但是此后i一直等于5,if语句的表达式的结果一直为真,不断执行continue语句……
  程序举例2:下面的程序输出什么?

#include<stdio.h>
#include<stdlib.h>
int main()
{
    int i = 1;
    while (i <= 10)
    {
        i = i + 1;
        if (i == 5)
            continue;
        printf("%d ", i);
    }
    system("pause");
    return 0;
}

  输出结果:
  【C语言】"for" "while" "do……while"
  分析:i=1,while语句的表达式结果为真,i自增1(此时i等于2),if语句的表达式结果为假,输出2,进入第二次循环……当输出4后,进入下次循环,i自增至5,此时if语句的表达式结果为真,执行continue语句,终止本次循环(不输出5),进入下次循环,i自增至6……(i不再等于5,则输出6~11。
  从上面的两个例子可以发现,在while循环中continue语句的位置不同,输出结果差异很大,所以大家应该特别注意continue语句所处的位置,仔细分析代码,以免出现错误。
  再来看一段代码:

#include<stdio.h>
#include<stdlib.h>
int main()
{
    int ch = 0;
    while ((ch = getchar()) != EOF)
        putchar(ch);
    system("pause");
    return 0;
}

  运行结果:
  【C语言】"for" "while" "do……while"
  其中,getchar()是字符输入函数,没有参数,其作用是从终端(或系统隐含指定的输入设备)输入一个字符。相应的putchar()为字符输出函数,作用是向终端输出一个字符。
  代码分析:定义一个整型变量ch,while语句的表达式中变量ch接收一个字符(从键盘上输入),然后判断是否等于EOF(文件结束标志),若不等于,则输出刚才输入的字符,直到输入的字符等于EOF。
  EOF:End Of File,C标准函数库中的文件结束符,其值通常为-1。在while循环中以EOF作为文件结束标志,这种以EOF作为文件结束标志的文件,必须为文本文件,因为在文本文件中,数据都是以字符的ASCII代码值的形式存放的。
--------------------------------
  *do……while语句*
  一般形式: do
         循环语句
        while(表达式);
  还是上面的例子,我们用do……while语句实现一下:

#include<stdio.h>
#include<stdlib.h>
int main()
{
    int i = 1;
    do
    {
        printf("%d ", i++);
    } while (i<=10);
    system("pause");
    return 0;
}

 输出结果:
 【C语言】"for" "while" "do……while"
  do……while语句的执行过程:先无条件地执行循环体,然后检查条件是否成立,若成立,再执行循环体……如此反复,直到表达式的值等于0(“假”),此时循环结束。
  执行流程图如下:
  【C语言】"for" "while" "do……while"
  也就是说,do……while循环语句只少要执行一次循环体,使用的场景有限,所以不是经常使用。
--------------------------------
  *循环语句的效率问题*
  建议1:在多层循环中,如果有可能,应当将最长的循环放在最内层,最短的循环放在最外层,以减少 CPU 跨切循环层的次数。
  如下面的代码:

//代码1
for (row = 0; row<100; row++)
{
    for (col = 0; col<5; col++)
    {
        sum = sum + a[row][col];
    }
}
//代码2
for (col = 0; col<5; col++)
{
    for (row = 0; row<100; row++)
    {
        sum = sum + a[row][col];
    }
}

  代码对比分析:显然代码2比代码1效率更高一些。
  建议2:如果循环体内存在逻辑判断,并且循环次数很大,宜将逻辑判断移到循环体的外面。
  如下面的代码:

//代码3
for (i = 0; i<N; i++)
{
    if (condition)
        DoSomething();
    else
        DoOtherthing();
}
//代码4
if (condition)
{
    for (i = 0; i<N; i++)
        DoSomething();
}
else
{
    for (i = 0; i<N; i++)
        DoOtherthing();
}

  代码对比分析:
  程序3比程序4多执行了N-1 次逻辑判断。并且由于前者总要进行逻辑判断,打断了循环“流水线”作业,使得编译器不能对循环进行优化处理,降低了效率。如果 N 非常大,最好采用程序4的写法,可以提高效率;如果N 非常小,两者效率差别并不明显,采用程序3的写法比较好,因为程序更加简洁。
  *几种循环的比较:*
  ⑴以上三种循环都可以用来处理同一问题,一般情况下他们可以互相代替。
  ⑵在while循环和do……while循环中,只在while后面的括号内指定循环条件,因此为了使循环能正常结束,应在循环体中包含使循环趋于结束的语句(如i++等)。
  for循环可以在表达式3中包含使循环趋于结束的操作,甚至可以将循环体中的操作全都放在表达式3中。因此for语句的功能更强,凡是用while循环能完成的,用for循环都能实现。
  ⑶用while循环和do……while循环时,循环变量初始化的操作应该在while和do……while语句之前完成。而for语句可以在表达式1中实现循环变量的初始化。
  ⑷for循环、while循环和do……while循环,都可以用break语句跳出循环,用continue语句结束本次循环。
  
  此次对循环语句的介绍就到这里。由于博主水平有限,其中定不乏缺点和不足,热切期望得到读者的批评和指正,谢谢!