Discuz教程网

C语言案例教程 - 第四章 程序流程控制

[复制链接]
authicon 09927306 发表于 2011-1-8 13:05:17 | 显示全部楼层 |阅读模式
本帖最后由 09927306 于 2011-1-8 18:58 编辑

第4章:程序流程控制
【例4-1】
一个猜数游戏,将要猜的整数存放在变量magic中,程序运行时,提示游戏者通过键盘输入自己猜的数guess,若猜对了,即guess==magic,屏幕显示“**Right**”,然后结束程序运行;否则不予显示,直接结束运行。程序可编制如下:


  1.         #include <stdio.h>
  2.         main()
  3.           { int magic=123,guess;
  4.             printf("Enter your guess:");
  5.             scanf("%d",&guess);
  6.             if (guess==magic)
  7.                printf("**Right**\\n");
  8.           }
复制代码


如果用if-else语句替换if语句,还可以扩充上述程序的功能:当猜对时,屏幕显示“**Right**”;否则,显示“**Wrong”。程序修改如下:


  1.       #include <stdio.h>
  2.         main()
  3.           { int magic=123,guess;
  4.             printf("Enter your guess:");
  5.             scanf("%d",&guess);
  6.             if (guess==magic)
  7.                printf("**Right**\\n");
  8.             else
  9.                printf("**Wrong**\\n");
  10.          }
复制代码


【例4-2】
用嵌套的if语句还可以再扩充例4-1猜数游戏的功能:如果猜错了,屏幕除了显示“**Wrong**”外,还显示是猜大了或猜小了的信息,以帮助游戏者继续往正确处猜。显然,当程序执行到guess≠magic时,还要继续判断guess是大于magic还是小于magic,分别显示不同的信息。程序改写如下:


  1.         #include <stdio.h>
  2.         main()
  3.           { int magic=123,guess;
  4.             printf("Enter your guess:");
  5.             scanf("%d",&guess);
  6.             if (guess==magic)
  7.                printf("**Right**\\n");
  8.             else
  9.                { printf("**Wrong**");
  10.                  if (guess>magic)
  11.                     printf("Too high**\\n");
  12.                  else
  13.                     printf("Too low**\\n");
  14.                }
  15.           }
复制代码


【例4-3】
在直角坐标系中有一个以原点为中心的单位圆,今任意给出一点(x,y),试判断该点是在单位圆内、单位圆上,还是单位圆外?若在单位圆外,那么是在x轴的上方,是在x轴上,还是在x轴的下方?
图4-4
程序流程图
以原点为中心的单位圆方程为x2+y2=1,因此,对任意点(x,y),若x2+y2<1,则该点在单位圆内;若x2+y2>1,则该点在单位圆外;若x2+y2=1,则该点在单位圆上。这就形成了3个分支,而if语句只能解决二分支问题。为此,先将问题变成2个分支,即若x2+y2≤1,则该点在单位圆内或单位圆上;否则,该点在单位圆外。当x2+y2≤1成立时,可以用另一个if语句进一步判断该点是在单位圆上还是单位圆内。当该点在单位圆外时,还要考虑是在x轴的上方、下方还是x轴上,对这一三分支问题,还要仿照上面的方法将它变成二分支问题来处理。据此,可画出该问题的流程图,见图4-4,并根据流程图写出如下程序:


  1.         main()
  2.           { float x,y,z;
  3.             scanf("%f%f",&x,&y);
  4.             z=x*x+y*y;
  5.             printf("%.2f,%.2f\\t",x,y);
  6.             if (z<=1)
  7.                 if (z==1)
  8.                     printf("在单位圆上\\n");
  9.                  else
  10.                     printf("在单位圆内\\n");
  11.             else
  12.                  if (y>=0)
  13.                     if (y>0)
  14.                        printf("在单位圆外,x轴上方\\n");
  15.                     else
  16.                        printf("在单位圆外,x轴上\\n");
  17.                  else
  18.                     printf("在单位圆外,x轴下方\\n");
  19.            }
复制代码


【例4-4】
用if-else语句改写例4-3的程序。改写后的程序将更容易阅读。


  1.         main()
  2.           { float x,y,z;
  3.             scanf("%f%f",&x,&y);
  4.             z=x*x+y*y;
  5.             printf("%.2f,%.2f\\t",x,y);
  6.             if (z==1)
  7.                printf("在单位圆上\\n");
  8.             else if (z<1)
  9.                printf("在单位圆内\\n");
  10.             else
  11.                if (y>0)
  12.                   printf("在单位圆外,x轴上方\\n");
  13.                else if (y==0)
  14.                   printf("在单位圆外,x轴上\\n");
  15.                else
  16.                   printf("在单位圆外,x轴下方\\n");
  17.            }
复制代码


程序先判断以(x,y)为坐标的点是不是在单位圆上,然后再判断它是不是在单位圆内,如果这两种都不成立,则该点肯定在单位圆外。这时,同样先判断该点是不是在x轴的上方,然后再判断它是不是在x轴上,第三种可能就是在x轴的下方。
【例4-5】
从键盘接收一个字符存放在变量c中。若输入的是小写字母,则转换成大写字母,大写字母及其他字符均不必转换,并显示是输入了小写字母还是其他字符的信息。


  1.     main()
  2.       { char ch,c;
  3.         scanf("%c",&ch);
  4.         c=ch>=\'a\'&&ch<=\'z\'?ch-32:ch;
  5.         printf(ch>=\'a\'&&ch<=\'z\'?"Lower case chracter":"Other chracter");
  6.       }
复制代码


【例4-6】
从键盘输入不同的字母,显示不同的国家名称。


  1.       #include <stdio.h>
  2.         main()
  3.           { char ch;
  4.             ch=getchar();
  5.             switch(ch)
  6.               { case \'a\':
  7.                   printf("America\\n");
  8.                 case \'b\':
  9.                   printf("Britain\\n");
  10.                 case \'c\':
  11.                   printf("China\\n");
  12.                 case \'d\':
  13.                   printf("Denmark\\n");
  14.                 default:
  15.                   printf("Japan\\n");
  16.                }
  17.            }   
复制代码




上一章:C语言案例教程 - 第三章 数 据 运 算
下一章:C语言案例教程 - 第五章 数组和字符串




上一篇:C语言案例教程 - 第三章 数 据 运 算
下一篇:C语言案例教程 - 第五章 数组和字符串
authicon  楼主| 09927306 发表于 2011-1-8 13:06:06 | 显示全部楼层
本帖最后由 09927306 于 2011-1-8 18:59 编辑

【例4-7】
修改例4-6的程序,使之能在输入某个字母后,只显示该字母打头的国家名称。


  1.         #include <stdio.h>
  2.         main()
  3.           { char ch;
  4.             ch=getchar();
  5.             switch(ch)
  6.                { case 'a':
  7.                    printf("America\n");break;
  8.                  case 'b':
  9.                    printf("Britain\n");break;
  10.                  case 'c':
  11.                    printf("China\n");break;
  12.                 case 'd':
  13.                   printf("Denmark\n");break;
  14.                  default:
  15.                   printf("Japan\n");
  16.               }
  17.            }
复制代码


程序运行时,每次输入一个字符,只显示一个国家的名称。例如,输入字母a,只显示America。
【例4-8】
编制一个程序,将50以内的奇数在屏幕上显示出来。
题目要求显示的数是有规律的。假设要输出的数是i,i的变化规律是从1开始,每次递增2,一直到49。因此,若以i为循环变量,则其初值为1,终值为49,步长值为2,且每次循环要进行的操作是输出i的值。一旦确定了for循环的3个表达式和循环体,就可以写出以下程序:


  1.         main()
  2.           { int i;
  3.             for (i=1;i<50;i+=2)
  4.               printf("%d",i);
  5.             printf("\n");
  6.           }
复制代码


程序中的printf("%d",i)是循环体,重复执行的部分,要被执行25次,这个次数是由循环变量的初值、终值和步长值确定的,计算公式为:
floor((终值–初值+步长)/步长)=floor((99–1)/2)+1=25
公式中的floor()函数用来取商的整数部分。
注意,程序中第二个printf()不是循环体的一部分,退出循环时,它才被调用。其目的是在输出一个数后不换行,继续输出下一个数,直到循环结束时,才换入下一行。
【例4-9】
编制一个求n!的程序。n的值由键盘输入。
这是一个求连乘积的问题,是一个基本的程序设计模块。解这类问题的关键是找出通用计算公式,即找到循环体。该问题的通用计算公式为:p=p*i。公式中,p既作为一个乘数使用,也用于存放连乘的结果,其初值为1;i既作为另一个乘数使用,也作为循环变量,其值从1变化到n。对每个i值,要进行一次p=p*i的计算。例如,当i=1时,p=1×1=1;i=2时,p=1×2=2;i=3时,p=2×3=6;……我们称这一计算过程为递推或迭代。当计算到i=n时,p中存放的就是n!。程序编制如下:


  1. main()
  2. { int i,n,p;
  3. scanf("%d",&n);
  4. p=1;
  5. for (i=1;i<=n;i++)
  6.            p=p*i;
  7.      printf("%d  %d\n",n,p);
  8.   }
复制代码


【例4-10】
编制程序求s=1+2+3+…+100。
这是一个求累加和的问题,求解思路与连乘积问题非常类似。先分析得到通用计算公式为:s=s+i。公式中,s既作为一个加数使用,也用于存放累加的结果,其初值为0;i既作为另一个加数使用,也用于控制循环终止,其值从1变化到100。对每个i值,要进行一次s=s+i的计算。例如,当i=1时,s=0+1=1;i=2时,s=1+2=3;i=3时,s=3+3=6;……当计算到i=100时,s中存放的就是1~100这100个数的累加和。程序编制如下:


  1. main()
  2. { int i,s;
  3. s=0;
  4. i=1;
  5. while (i<=100)
  6.        { s=s+i;
  7.              i++;
  8.        }
  9.        printf("s=%d",s);
  10.   }
复制代码


该程序有两点需要读者注意。其一,程序的循环体中有2条语句,s=s+i用来求累加和,i++用来修改i的值,i值的修改既能使累加的过程逐步向前推进,又能修改循环测试表达式中的变量值,使循环逐步趋向结束;其二,程序的开始处有赋值语句s=0和i=1,它们分别给累加变量s和循环变量i赋初值。
【例4-11】
自然常数e的计算公式为 。请编制程序计算e的近似值,要求被舍弃的首项 <0.000001。
这是一个既要求连乘积,又要求累加和的问题。用e表示级数前n项的和,用t表示级数的一个项,用n对项数计数,用e=e+t来累加各个项。如果|t|≥0.000001,就继续累加,否则循环结束,打印累加和e。为了简化编程,将各个级数项分母上的连乘转化成连除。程序如下:


  1.      #include <math.h>
  2. main()
  3.           { int n=1;
  4.             float e=0,t=1;
  5.             while (fabs(t)>=1E-6)
  6. { e=e+t;
  7. t=t/n;
  8.                n++;
  9.              }
  10.            printf("e=%f\n",e);
  11.         }
复制代码


程序运行时,在进入循环前,有e=0(初值)、n=1和t=1(即级数的第1项),由于循环条件满足,因而进入第一轮循环。在循环体中,先将t累加到e上,使e=1,然后计算t=t/1=1(即级数的第2项),并将n增加到2,经判断循环条件仍满足,因此进入第二轮循环。同样先将t累加到e上,使e=e+t=1+1=2,然后计算t=t/2=1/2(即级数的第3项),并将n增加到3。到第三轮循环时,e=e+t=2+1/2,级数的下一项t=t/n=1/2/3,n被增加到4。依此类推,每进入新一轮循环时,若上一轮循环中得到的t的绝对值不小于0.000 001,就先将该项累加到e上,然后计算级数的后一项,并使n=n+1。若|t|<0.000 001时,退出循环,执行输出e值的操作。程序运行结果为:

e=2.718 282

楼下还有
authicon  楼主| 09927306 发表于 2011-1-8 13:06:28 | 显示全部楼层
本帖最后由 09927306 于 2011-1-8 19:00 编辑

【例4-12】
从键盘输入1个整数,把这个整数中的各位数字反序显示出来。例如,输入为1234,则输出为4321。
所谓反序显示就是先显示个位数,再显示十位数……对任意整数x而言,可以用x%10求得其个位数,例如,1234%10=4。在此基础上,用x/10将x缩小10倍。例如,1234/10=123。这样,x就由原来的4位数变成了3位数。用同样的方法可以求得该3位数的个位数(实际上是原4位数的十位数),再将3位数缩小为2位数,直至1位数。在1位数的情况下,直接输出该数,整个问题就解决了。剩下的问题是如何判断x已经缩小为1位数,若x为1位数,必有x/10==0。因此,解决这个问题的基本思路是将大事化小,小事化了,每次循环要做的工作是求出x的个位数,将该个位数输出,然后将x缩小10倍。如果缩小后的x不等于0,就继续进入下一轮循环;否则,退出循环。程序如下:


  1.         main()
  2.           { int x,c;
  3.             printf("Input an integer:");
  4.             scanf("%d",&x);
  5.             do
  6.               { c=x%10;
  7.                 printf("%d",c);
  8.               } while ((x/=10)!=0);
  9.             printf("\n");
  10.           }
复制代码


【例4-13】
打印九九乘法表。
如果用for循环的嵌套来实现,可以用外层循环控制被乘数i的变化,用内层循环控制乘数j的变化,内层循环的循环体要进行的操作是计算i*j,输出结果。外层循环的循环体包括整个内层循环及退出内层循环后才执行的printf("\n")语句。程序如下:


  1.         main()
  2.           { int i,j;
  3.             for (i=1;i<=9;i++)
  4.               { for (j=1;j<=9;j++)
  5.                  printf("%d*%d=%2d ",i,j,i*j);
  6.                 printf("\n");
  7.               }
  8.           }
复制代码


程序的执行过程是:
(1)先对外层循环的循环变量i赋初值1,由于循环条件成立,执行外层循环的循环体,即进入内层循环;
(2)在内层循环中,同样先对内层循环的循环变量j赋初值1,这时循环条件也成立,于是执行内层循环的循环体,即显示:
1*1=1
(3)修改循环变量j的值,使j=j+1,并判断循环条件仍然成立,继续执行循环体,显示:1*2=2
(4)重复执行(3),依次得到1*3=3,1*4=4,…,1*9=9,当j>9时退出内层循环,执行printf("\n"),使输出换行(注意,printf("\n")是外层循环的循环体,而不是内层循环的循环体)。然后第二次进入外层循环(即i=2),由于i<=9成立,于是又进入内层循环,内层循环变量j重新初始化为1,显示:
2*1=2,……
(5)如此反复,每一轮外层循环,都要重复执行内层循环9次,直到外层循环终止时,内层循环的循环体printf("%d*%d=%2d ",i,j,i*j)共被执行9*9=81次。而printf("\n")只是外层循环的循环体的一部分,共被执行9次。
程序输出结果如下:

1*1=1 1*2=2
1*3=3
1*4=4
1*5=5
1*6=6
1*7=7
1*8=8
1*9=9

2*1=2 2*2=4
2*3=6
2*4=8
2*5=10
2*6=12
2*7=14
2*8=16 2*9=18


……

9*1=9 9*2=18 9*3=27 9*4=36 9*5=45
9*6=54
9*7=63
9*8=72 9*9=81
【例4-14】
用迭代法求正数x(2~100)的平方根。求平方根的迭代公式如下:

x1=(x0+x/x0)/2
要求迭代精度为0.00001。
所谓迭代,就是从初始值x0出发,用迭代公式计算x1,当|x1–x0|<ε时(ε称为迭代精度),迭代收敛,x1就是所求的根;否则,用x1替换x0,继续使用迭代公式,计算新的x1。


  1.         #include <math.h>
  2.         main()
  3.           { float x,x0,x1;
  4.             for(x=2; x<=100; x++)
  5.               { x0=x/2;
  6.                 x1=(x0+x/x0)/2;
  7.                 do
  8.                   { x0=x1;
  9.                     x1=(x0+x/x0)/2;
  10.                   } while(fabs(x1-x0)>=1e-5);
  11.                 printf("%.0f    %f\n",x,x1);
  12.                }
  13.           }
复制代码


程序中,外层for循环用来依次从2~100中选出一个数,内层do-while循环用来求该数的平方根。在求某数x的平方根时,用x/2作为迭代初值。利用迭代公式求出x1,这是第一次迭代过程,然后在do-while循环中进行反复迭代,直到两次迭代结果的绝对误差小于指定的迭代精度时,x1就是对应x的平方根。
【例4-15】
break在循环结构中的控制作用示例。


  1. main()
  2.           { int t;
  3.             for (t=0;t<100;t++)
  4.               { printf("%d",t);
  5.                 if (t==10) break;
  6.               }
  7.           }
复制代码


如果程序中没有break语句,for循环将执行100次。由于break语句的存在,当t=10时,break被执行,程序流程被强迫退出循环,从而程序运行结束。程序运行结果为:
1 2 3 4 5 6 7 8 9 10
【例4-16】
continue在循环结构中的控制作用示例。


  1. main()
  2.           { int i=0;
  3.             while(i<100)
  4.               { i++;
  5. if (i%5==0) continue;
  6.                 printf("%d",i);
  7.               }
  8.             printf("\n");
  9.           }
复制代码


程序运行时,将100以内的自然数显示在屏幕上,但凡5的倍数均不显示。这是由于凡是遇到5的倍数时,在continue语句的作用下,程序流程跳过printf()语句,直接进入循环条件的测试。形象地说,continue是将它后面的循环体部分“短路”。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

1314学习网 ( 浙ICP备10214163号 )

GMT+8, 2025-5-3 19:09

Powered by Discuz! X3.4

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表