在C/C++以及其它现代编程语言中,都存在循环语句,它允许一个指令序列能被反复的执行,直到某个特定的条件被达到.这个条件可以是被预先定义的(如在for循环中),也可以是末端开口的(如while和do while循环).
for循环语句
for循环在其它语言中也有其它形式的定义,但是C/C++为我们提供了超出预料的强大而灵活的for语句.通用格式如下:
for( initialization; condition; increment ) statement;
for语句允许一些适量的变更,不过通常它的使用方式就是上面描述的样子.initialization是一个复制语句,用来设置条件控制变量.condition是一个关系表达式,用来确定循环何时结束.increment则描述了当每次循环重复执行的时候,控制变量如何变化.这三个部分必须用分号隔开.for循环将在condition表达式为true的时候循环执行,直到表达式的值变为false就跳出循环.下面的例子中,for循环将会在屏幕上显示1到100.
#include <stdio.h>
int main( void )
{
for( x = 1; x <= 100; x++ ) printf( "%d", x );
return 0;
}
循环中,x首先被初始化为1,然后与100比较.只要x仍小于100,pintf()函数就反复执行.每执行一次循环体,x的值就增加1,然后再次与100对比,看它是否始终小于或者等于100.直到x大于100时,循环结束.在这个例子中,x就是循环控制变量,它在每次循环中都被改变和比较.下面的例子,循环体中有多个语句.
for( x = 100; x != 65; x -= 5 ){
z = x*x;
printf( "The square of %d,%f", x, z );
}
x的平方和printf()函数调用语句都会反复运行直到x等于65.注意循环时负方向运行的,x被初始化为100,每一次循环都减少5.
for循环的条件检测是在循环体执行之前进行的,所以如果条件表达式返回值直接为false,循环体就一次也不会执行.
x = 10;
for( y = 10; y != x; ++y ) printf( "%d", y );
printf( "%d", y ); /* this is the only printf() statement that will execute */
for循环的其它格式
前面已经讲解了for循环的最常用的格式,for循环还有一些变化格式,能使得它在某些特定的程序中有更强的功能,灵活性和适应性.
一种常用的变化格式是,用逗号连接多个控制变量.(记住,逗号常可以连接多个表达式,它常有"do this and this"的含义.)例如,下面的程序就使用了x和y两个控制变量,它们都在for语句头部被初始化:
for( x=0, y=0; x+y<10; x++ ){
y = getchar();
y = y - '0'; /* subsract the ASCII code for 0 from y */
.
.
.
}
逗号则用来格开两个初始化语句.每一次循环重复的时候,x的值都增加1,y的值则由键盘输入确定.必须x和y在一个特定的值的时候,循环才能中止.尽管y的值由键盘输入决定,但是它必需在for循环的判断表达式第一次求值之前被初始化.
下面来看一个示例,其中的函数converge(),演示了多重控制变量的for循环的实际应用.coverge()函数用来将一个字符串的内容拷贝到另一个字符串中,字符串的拷贝从两端开始收敛于中间:
/* Demonstrate multiple loop control variables. */
#include <stdio.h>
#include <string.h>
void converge( char *targ, char *src )
int main( void )
{
char target[80] = "xxxxxxxxxxxxxxxxxxxxxxxxxxx";
converge( target, "This is a test of converge()." );
printf( "Final string: %s/n",target );
return 0;
}
/* This function copies one string into another.
It copies characters to both the ends,converging at the middle. */
void converge( char *targ, char *src )
{
int i, j;
printf( "%s/n", targ );
for( i=0, j=strlen(src); i<=j; i++,j-- ){
targ[i] = str[i];
targ[j] = str[j];
printf( "%s/n", targ );
}
}
下面是该程序的输出:
xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Txxxxxxxxxxxxxxxxxxxxxxxxxxxx
Thxxxxxxxxxxxxxxxxxxxxxxxxxxx.
Thixxxxxxxxxxxxxxxxxxxxxxxx).
Thisxxxxxxxxxxxxxxxxxxxxxx().
This xxxxxxxxxxxxxxxxxxxxe().
This ixxxxxxxxxxxxxxxxxxge().
This isxxxxxxxxxxxxxxxxrge().
This is xxxxxxxxxxxxxxerge().
This is axxxxxxxxxxxxverge().
This is a xxxxxxxxxxnverge().
This is a txxxxxxxxonverge().
This is a texxxxxxconverge().
This is a tesxxxx converge().
This is a testxxxxconverge().
This is a test xx converge().
This is a test of converge().
converge()函数中的for循环使用了两个控制变量i和j,用来从两个相反的方向索引字符串.随着循环的重复,i不断增加,j不断减少,当i大于j的时候循环中止,这样就保证了i始终是大于j的.条件表达式不一定非要是把控制变量与某个特定的目标值对比.实际上,条件表达式只需为某个关系或者逻辑语句.所以可以根据自己的需要设定多种条件表达式.
例如,可以用下面的函数来使用户登录进入远程系统:
void sign_on( void )
{
char str[20] = " ";
int x;
for( x=0; x<3 && strcmp( str, "password" ); x++ ){
printf( "Enter password please:" );
gets( str );
}
if( x==3 ) return;
/* else log user in ... */
}
用户可以有三次机会输入密码,当用户输入正确的密码,或者输入错误密码三次,循环将会中止.函数中用到的strcmp是标准函数库中的函数,用来比较两个字符串,如果它们匹配的话就会返回0.
记住,for循环的三个部分都必须由有效的表达式组成.但是,未必每个部分的表达式都要按照常规的用法习惯来定义.例如:
#include <stdio.h>
int sqrnum( int num );
int readnum( void );
int prompt( void );
int main( void )
{
int t;
for( prompt(); t=readnum(); prompt() )
sqrnum( t );
return 0;
}
int prompt( void )
{
printf( "Enter a number: " );
return 0;
}
int readnum( void )
{
int t;
scanf( "%d/n", &t );
return t;
}
int sqrnum( int num )
{
printf( "%d/n", num*num );
return num*num;
}
仔细看看这段代码,for循环的三个部分都由函数调用组成.它们提示用户输入数字,然后从键盘读取用户输入的数字.当用户输入为零的时候,第二个表达式的值将为false,则循环停止.反之,程序将会输出数字的平方值.在这个例子中,for循环的初始化和条件判断都和常规的方式不同,但是整个for循环中的三个部分都是有效的.
for循环的另外一个有趣的特性是它在定义时的三个部分可以不存在.也就是说这三个部分的表达式是可选的.例如,下面的for循环在用户输入123之前会一直循环不停止:
for( x=0; x!=123; ) scanf( "%d", &x );
for循环定义的第三个部分也就是通常的控制变量变值的部分是空的.每次循环都将检测x是否等于123,没有其它操作.当用户输入的数值等于123的时候,条件表达式的返回false,循环中止.
循环控制变量的初始化也可以在循环外进行.这种情况常发生在控制变量的初始化值需要预先经过复杂的计算产生的情况下.
gets( s ); /* read a string into s */
if(*s) x = strlen(s); /* get the string's length */
else x = 10;
for( ; x<10; ){
printf( "%d", x );
++x;
}
无限循环
尽管可以利用任何循环语句定义无限循环,但是传统的习惯是采用for语句来完成这个工作.因为,for循环定义的三个部分都可以为空,也就是说第二部分的条件表达式也可以空白,所以可以使用第二部分为空的方式定义无限循环:
for( ; ; ) printf( "This loop will run forever./n" );
条件表达式不存在的情况下将被默认为true.我们也可以定义第一和第三部分,但是通常不需要.不过并不一定这样的for语句就一定能无限循环下去,因为break语句也能发挥作用.在循环体的任何地方,只要遇到了break语句,怎循环会立即退出.如下面的例子:
ch = '/0';
for( ; ; ){
ch = getchar(); /* get a character */
if( ch=='A' ) break; /* exit the loop */
}
printf( "you typed an 'A' );
这个循环是无限循环,但是当用户键入A的时候将中止.
没有循环体的for循环
for循环的循环体语句可以不存在.可以利用这种形式来增加某些特性运算的性能或者做延时循环.清楚输入中的空格就是最常见的任务.例如,在某个数据库程序中,可能有一些字符串如"show all balances less than 400.",数据库需要得到单个词的反馈,并且单词前不能带空格.也就是说数据库的输入处理部分可以识别"show",但是不能是" show".下面的程序可以完成这样的功能.
for( ; *str == ''; str++ )
这个循环就没有也没有必要有循环体.
延时循环在程序中也很常用,下面是一个例子:
for( t=0; t<SOME_VALUE; t++ );