欢迎访问志愿传奇

高考倒计时23

立身以力学为先,力学以读书为本。——欧阳修

您所在的位置: 新考网(原中国大学在线)>>教学教育 > 正文内容

《C语言程序设计》顺序、选择、循环结构习题课教 案 1

作者:  时间: 2017-04-16

 

   

一、循环嵌套  二、图阵数阵   三、数域遍历

   

  

      

   

一、循环嵌套

顾名思义,就是一个循环体内存在着另一个循环 整体。

 如:while (        )                  

        {

           for(  )

            {

          …………

             }

         }

 

   

   

下面请看什么是一次?什么是一遍吧?

如:

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

   

             for ( j=1 ;   j<=10;     j++ )

 

                          n++;

   

   

i=2,是外循环的一次循环,但内循环却要从J110地运行10次,这就是一遍!!

1、如果把N++这条语句换成别的语句会是什么样呢?

2、又如果把for ( j=1; j<=10; j++ )换成for(j=1;j<=I;j++)又会是什么样?

   

例如:请判断下列程序输出结果

     int  a=0,b=0,k,j;    

     for(k=1;k<=10; k++)

        {     

            a=a+1;  b=0;    

            for  (j=1; j<= 10; j++)

             {

               a=a+1 ; b=b+2;

             }           

        }

       printf("%d  %d\n", a,b);

   

要我们判断a,b的值,关键是我们要知道a=a+1以及b=b+2的执行次数。而内循环中有a=a+1,外循环中也有a=a+1,但他们的执行次数是不同的;外循环中a=a+1只执行10次,也就是给a 加了101,而内循环中a=a+1却执行了100次,所以a=a+1共执行了110次,最终a 的值是110;由于b=0要执行10次也就是要清0十次,在前9次中,不管b的值是多少,第十次还是要清0的,所以我们只要从最后一次b0开始,b=b+2只有最后10次执行的值才有效,故b的值最终是20

   

   

   再例如: int I,k,m,a=3;

           for  ( I=1 ;I<=5  ; i++){

              a=a+3;               ………   执行5

              for (k = 1 ; k<=6 ; k++){

                  a=a+3;              ……   执行5*6

                  for(m = 1 ; m<= 7 ; m++){

                    a=a+3;         ……   执行5*6*7

            }}}

            Printf(“%d”, a)

 同上理a 的值应是738

   

请同学们自己分析下列程序段:

      int h,j,k,n=0;     

     for(h=1; h<=10; h++ )

           for (j =1 ;j<= h; j++)

              for ( k=j ;k<=3; k++)

                 n = n  +  1;       

        printf("%d", n);      

程序的输出结果是    56   

当然,循环嵌套不光是由FOR循环构成,while DO 都能构成循环嵌套。而由FOR构成的循环嵌套具有明确的循环次数,其它语句构成的循环嵌套虽然也有循环次数,但不是程序所关心的。

   

课堂练习:

1、计算1+2+3+4……+N!(N是一个从键盘输入的正整数)

   

   

2、编程打印如下图阵:

                               ****

                               ****

                               ****

                               ****

二、图阵与数阵

图阵与数阵即把某种字符或数字排成一个图形或一个方阵。这要求我们研究阵列中行与列的关系并灵活控制输出格式。虽然要求较高,但也有规律可循,下面我们结合实例一一剖析。

先请看一个简单的图阵:

   

①输出如下图阵

$

$ $

$ $ $

$ $ $ $

$ $ $ $ $

该阵有5行,第I 行有I列;

一般我们考虑用外层循环控制行数,内层循环控制列数,所以程序如下:

Int I,j;

for (I = 1;I <= 5 ;i++)       ‘……图阵中有五行

for(j = 1; j<=I;j++)              ‘……每行共有I

  printf(“$”);

  printf(“\n”);                       ‘……换行

   

②输出如下图阵

               &

            & & &

         & & & & &

      & & & & & & &

此图阵较以上图阵,多出一个要求是:如何控制每一行第一个“&”的输出位置。可考虑如下方式:

   

 For(I =1;i<=4;i++) {

For(k=1;k<=30-I;k++)Printf(“ ” ); 

                                          ‘…控制行首位置

For(j = 1; j<=2 * I–1 ; j++)   

                                          ‘……I行有2*I-1

    Printf(“&”);

   

   Printf(“\n”);

          }

   由以上两例可知,第I行有多少列这个通项很重要。

   

③再如:输出如下星阵:

                 *

              * * *

            * * * * *

         * * * * * * *

            * * * * *

               * * *

                  *

星阵有七行,那么第 I 行有多少列呢?不是解决这类问题的关键

I 行有 7 – 2 * abs( 4 – I ) 列,所以该程序如下:

   

    int i,k,j;

      

        for(i =1; i<= 7; i++){

            

     for (k=1;k<=(20+abs(4-i));k++)printf(" ");

   

     for (j=1; j<=(7-abs(4-i)*2); j++) printf("*");

   

     printf("\n");

   

④输出如下数字阵列

1

1 2

1 2 3

1 2 3 4

1 2 3 4 5

数阵与图阵不同,数阵的列有数值大小的问题而图阵则没有这个要求;故一般用数组先存储数值而后输出。由于本例较简单,可直接输出,如何用数组这种形式输出该阵请同学们在学完数组一章后自己考虑

   

程序如下:

int i,k,j;

for(i=1;i<=5;i++){

for(j=1;j<=i;j++)

注意输出的数值大小与两个循环变量之间的关系

printf("%d",j);  

      printf("\n");}

   

请再看看如下数阵:

                    1 

                1   2   1 

            1   2   3   2   1

         1  2   3   4   3   2   1

      1  2  3   4   5   4   3   2   1

同以上星阵,也得控制输出位置;有五行,第I行有2*I1列,且输出项是两头小,中间大的数值形式,变化很有规律。

   

For (i=1;i<=5;i++){

   For(k=1;k<=30-I;k++)printf(“ ”);

   For(j=1;j<=2*i-1;j++)

        Printf(“%d”,5-abs(i-5));

   Printf(“\n”);

能输出: 

                    1

                2  2  2

           3  3   3  3  3

        4  4  4  4  4  4  4

     5  5  5  5  5  5  5  5  5

为什么呢?

因为输出项表达式一定与变量J有关,象5-abs(i-5)这样一定不行。只要把输出项表达式换成i-abs(i-j)就行了!

   

好的,再来看看如下数阵:

   

   

   

   

                   1

                1  2  1

             1  2  3  2  1

          1  2  3  4  3  2  1

       1  2  3  4  5  4  3  2  1

          1  2  3  4  3  2  1

             1  2  3  2  1

                1  2  1

                   1

几乎是以上两个数阵的对称合并。

   

我们先把上述程序控制行的外层循环换成:

for (i=1;i<=9;i++){,控制输出位置的循环换成:for(k=1;k<=30+abs(i-5);k++)printf(" ");

控制输出个数的内层循环写成:for(j=1;j<=9-2*abs(i-5);j++)

输出项表达式不变就能得到:如下数字阵列:

                   1

               1  2  1

           1  2  3  2  1

       1  2  3  4  3  2  1

   1  2  3  4  5  4  3  2  1

       1  2  3  4  5  6  5

           1  2  3  4  5

               1  2  3  

                   1

   

当然这不是我们所要的数阵了!右上角的数字没有跟上变化!

   

大家思考一下:我们可以把Printf(“%d”,5-abs(i-5))中的I5-abs(i-5)替换就行了!所以以上数阵的程序如下:

{int i,k,j;

      

       for (i=1;i<=9;i++){

  for(k=1;k<=30+abs(i-5);k++)printf(" ");

   for(j=1;j<=9-2*abs(i-5);j++)

        printf("%d",(5-abs(i-5))-abs(5-abs(i-5)-j));

   printf("\n");

       }

 }

三、数域的遍历

1、顾名思义是对某个范围中所有数,从头到尾经过一遍,查找符合条件的数。

例如:求1100以内不能被3整除的整数的个数。

分析:1100 就是一个数域,每个数都验一遍,能被3整除的就记录下来,即:

    ForI = 1i<=100;i++{

       if (I % 3 == 0) continue;  n = n + 1;}

    printf(“%d”,n);

   

      一般地对某个数域进行查找,可考虑使用FOR循环,然后对循环变量进行条件测试。如古典数学问题:

百钱百鸡

百马百担(请同学们自己动手解决)

   再例:求1+3+5+……99的值

   该题要求把这个数域中的所有数累加起来,程序如下:

for I = 1;i<=100;i++ s=s+I;

则结果的值在S中。

类似的题目如下:(同学们自己动手)

1*2*3*4*……99的值

1+1/2+1/3+……+1/1000的值     1-1/2+1/3-……-1/1000的值

   

2、另一例数域的遍历,是不清楚这列数每个数的具体大小,但也可以根据初值和相邻两数的关系,一个挨一个地计算出这列数的每个数。

例如:山中有一堆核桃,小猴子看到后吃了一半,觉得不过瘾又多吃了一个,第二天又把剩下的核桃吃了一半,又多吃了一个,按这种吃法,到了第十一天只剩下一只核桃,问这堆核桃共有多少个?

这个问题与以上问题不同的是,只知道结果求最初的值,但我们不难想到,相邻两天的核桃数有如下关系:Xn = Xn + 1 + 1 * 2 也就是说,X1X2X3……X11=1,这列数有如上关系,我们只要知道初值就能很容易地推导出第二个值、第三个值……。因此对于这类问题,我们只需要把握初值,通过一次又一次的代入关系式就能得到第二个值,第三个值……

   

那么程序如下:

 Int i,t  = 1;

 For(i = 1;i<=10;i++)t =(t+1) * 2;

 Printf(“这堆核桃共有%d”,t);

 

这类问题,我们归纳为数列问题。尽管也是对这列数的遍历,但是与前述不同的是这列数不是已知的,需要我们逐次求出。再看一例:

一球从100米高度自由落下,每次落地反跳回原高度的一半再落下,求它在第十次下落时共经过多少米?第十次反弹多高?

分析:已知数据的第一项,且相邻两数据项的关系是1/2,另外,注意球是先落下后弹起。解:

   

解:

      Int I,h = 100,  s = 100;

      for (I =1;i<=9;i++){h = h /  2; s = s + 2 * h}

     printf   s , h /2  ……第九次下落的高度的一半即第十次反弹高度


加入家长群

QQ扫一扫,加入家长群

关注我们

关注微信公众号,了解最新精彩内容

关注抖音号

抖音扫一扫,立即关注我