第5章迭代与循环结构许多问题可以通过重复相同的操作来完成,通过指定次数或设定条件来控制执行过程。多次重复执行的结构称为循环,每一次循环称为迭代。 5.1循环结构 假如要求系统输出5个随机数,可以重复写5条输出随机数的语句。如果要求输出10个随机数怎么办?100个呢?此时可以利用循环语句,设计一个变量n记录要输出的随机数的个数,再定义一个计数器变量counter,初始值为1,每一次循环,输出一个随机数,然后计数器加1,当计数器大于n时循环结束。这样就可以根据用户的要求,用一条输出语句重复执行若干次得到结果。用流程图表示的这个程序如图51所示。 图51输出5个随机数的程序流程图 计算机的运算速度很快。只要找到解决问题的规律,学会循环语句,掌握控制循环条件的方法,其余的工作就可以交给计算机完成。〖3〗程序设计基础及应用(C&C++语言)第5章迭代与循环结构〖3〗5.2循环控制语句 在C&C++中,常见的循环控制结构有while循环、do…while循环和for循环。while循环与for循环是当型循环,当满足条件时开始迭代,然后再判断条件;而do…while循环是直到型循环,首先开始迭代,然后判断条件,决定是否重复迭代。 5.2.1while语句 while循环语句的特点是先判断条件,然后确定是否执行循环体。当条件为true(0)时,执行循环体,然后再判断条件,重复执行循环体,直到条件为false(0)。 while循环语句的一般形式为while (表达式) { 循环体 }其中: (1) 表达式放在while后的小括号内,可以是任何表达式(true或非0值表示真,false或0值表示假),也可以省略表达式(永远为真)。若表达式的值为真,则循环执行循环体的语句,否则退出循环。 (2) while后面的循环体在逻辑上只能是一条语句,因此循环体一般是一条复合语句,用一对大括号括起来。如果只有一条语句,大括号可省略。 循环能够执行若干次,则条件表达式或循环体中一定有关于循环终止的语句。否则循环一直无限重复,称为无限循环或死循环。 while循环的执行流程为: ①计算表达式的值,若值为真,执行大括号内的语句; ②再次计算表达式的值,若值为真,则再次大括号内的语句; ③重复,直到表达式值为假,终止循环,继续向下进行。while循环语句流程图如图52所示。图52while循环语句流程图 【例51】使用while循环显示0~99,各数字间有一个空格,每行显示5个数字。1#include 2using namespace std; 3int main() 4{ 5int x=0; 6while(x<100) 7{ 8cout<< x <<" "; 9x++; 10if(x%5==0) 11cout< 2using namespace std; 3int main() 4{ 5int i, sum=0; 6for ( i=1; i<=100; i++) 7{ //本例的for语句只有一条赋值语句,可以不写大括号 8sum = sum + i; //等价于sum += i ; 9} 10cout<< "Sum: " << sum << "\\n"; 11return 0; 12}对本程序适当做些修改,就可以实现其他类似的功能: (1) 求1 + 3 +… + 99。 从第2个数起,每个数比前一个数大2,将第6行i++改为i+=2。 (2) 求1 - 2 + 3 - 4 +… -100。 从第2个数起,每个数比前一个数的绝对值大1,符号位相反,则增加一个保存符号的变量flag,然后在每次求和后修改flag的值为-flag,第5~9行代码段改为int i, sum=0 ,flag =1; for ( i=1; i<=100; i++) { sum = sum + flag  i; flag = -flag; }(3) 求n!。与求和代码类似,将积的初始值设为1,将累加运算改为累乘运算。第5~9行代码段改为int i, sum=1; for(i=1; i<=10; i++) { sum = sum  i; //等价于sum = i; }for循环功能强大而灵活,因此它的变化形式也很多。下面仍以求 1~100 的和为例,介绍for的几种变化形式。 5.2.2.1for的变化形式1: 表达式1由多个表达式组成 如果在表达式1中给多个变量赋值,必须用逗号分隔它们(称为逗号表达式,表达式的值就是最后一个表达式的值)。例如: int i,sum; for(i=1, sum=0; i<=100; i++) sum = sum + i;上述程序段中,声明了两个int型变量i和sum,在for循环语句的表达式1中为两个变量初值,两个赋值语句以逗号分隔,且以分号结尾。 5.2.2.2for的变化形式2: 表达式1为空 可将表达式1的语句移到for循环语句之前,但for语句中的分号不可省略。例如: int i=1,sum=0; for(; i<=100; i++) sum = sum + i;5.2.2.3for的变化形式3: 表达式3为空 可将表达式3移到循环体内,但for语句中分的分号不可省略。例如: int i, sum=0; for(i=1; i<=100;) { sum = sum + i; i++; }5.2.2.4for的变化形式4: 表达式2为空 若表达式2为空,则循环条件一直为真,可以将表达式2的值写到循环体内,用break语句退出循环。同样,for语句中的分号不可省略。例如: int i, sum=0; for(i=1; ; i++) { sum = sum + i; if(i>100) break; //结束循环 }5.2.2.5for的变化形式4: 3个表达式全为空 for循环语句内的3个表达式都可以省略,但分号不可以省略。此时for循环语句退化为while(true),表示循环条件永远为真。int i=1,sum=0; for(;;) { sum=sum+i; i++; if(i>100) break; }5.2.2.6for的变化形式5: 表达式 3由逗号表达式组成 可将for循环体内的语句转移到表达式3中,此时表达式3由多个表达式组成,它们用逗号分隔,按顺序执行。为了保证程序的可读性,不提倡这种用法。例如: int i=1, sum=0; for(i=1; i<=100; sum=sum+i, i++) ;或for(i=1; i<=100; sum=sum+i, i++); //末尾有分号,表示条件为真时执行空语句或: for(i=1; i<=100; sum=sum+i, i++) { }这3个for语句的功能相同。 5.2.3do…while语句 do…while循环语句是先执行循环体,再判断是否继续下一轮迭代的循环语句。do…while是直到型循环,也就是说,首先执行一次迭代,然后再判断条件,若满足了就重复。直到型循环与当型循环的区别是: 当循环条件初始值为假时,直到型循环要执行一次迭代,而当型循环什么也不做。 do…while语句的一般形式为do { 循环体 } while(表达式);do…while语句执行流程为: 先执行大括号里的循环体,再计算表达式的值。若表达式为真,继续执行循环体,重复判断表达式的值,直到表达式为假时终止循环。do…while循环语句流程图如图54所示。图54do…while循环语句流程图 【例53】输入若干个字符,以'@'字符结束。统计并输出小写英文字母的个数。1#include 2using namespace std; 3int main() 4{ 5int count = 0; 6char ch; 7cout << "Input characters:\\n"; 8do 9{ 10cin >> ch; 11if(ch >= 'a' && ch <= 'z') 12count++; 13} while(ch!='@'); 14cout << "There are " << count << " lowercase(s).\\n"; 15return 0; 16}运行示例如下: Input characters: ab123 dfIOz fd@ There are 7 lowercase(s).初始化变量count值为0,作为计数器。在do…while 循环中,检查条件前进入循环体,因此循环体至少执行一次。第11行判断条件,若输入的字符是小写字母,则执行第12行的语句: 计数器count加1。执行到第13行,循环条件若为真,就跳转到循环的开始处(第8行)继续执行,否则结束循环,从第14行继续向下执行执行。在本例中,用户输入3行字符,只有7个是小写字母: abdfzfd。 5.2.4陷阱: 循环的常见问题〖*2〗5.2.4.1死循环死循环是程序设计中经常会遇到的一个现象,指程序的循环条件一直为真,程序一直陷入在循环语句中,也称为无限循环。一旦程序进入死循环,光标会一直闪烁,按任何键均无反应,此时只能按Ctrl+C组合键强行终止程序的运行。 造成死循环的主要原因是循环中缺少能让循环条件变假的操作。 【例54】死循环示例。 下面几个程序都会陷入死循环,请观察它们与例51的区别,找到错误并修改。(a) 1#include 2using namespace std; 3int main() 4{ 5int x=0; 6while(x<100) 7cout<< x <<" "; 8x++; 9if(x%5==0) 10cout< using namespace std; int main() { int x=0; while(x<100) { cout<< x <<" "; if(x%5==0) cout< using namespace std; int main() { int x=0; while(0= #include #include using namespace std; double Cbrt(double x);//自定义函数求x的立方根,为了与库函数区分,首字母大写 int main() { double x; cin >> x; cout << fixed << setprecision(15); cout << Cbrt(x) << endl; //调用自定义函数求x的立方根 cout << pow(x,1.0/3) << endl; //调用cmath中的pow函数求x的1/3次幂 cout << cbrt(x); //调用cmath中的cbrt函数求x的立方根 return 0; } double Cbrt(double x) { double x1=1, x2 ; while(1) //也可以写为while(true)或while() { x2 = ( 2  x1 + x / (x1  x1 ) ) / 3; if ( fabs ( ( x2 - x1 ) / x1 ) < 1e-6 ) break; x1 = x2; } return x2; }运行示例如下: 29 3.072316825686780 3.072316825685847 3.072316825685848说明: 本例可以不用break语句,Cbrt函数定义可修改为 double Cbrt(double x) { double x1,x2=1; do {