第五章 循环结构课后反思

Posted daiqiu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第五章 循环结构课后反思相关的知识,希望对你有一定的参考价值。

本章重点、难点:

一、for语句

1、for语句的一般形式:


for(<初值表达式>;<条件表达式>;<循环变量表达式>)
{
<循环体语句>
}

2、for语句的重要特征

  • <初始表达式>可以省略,但需保留(;),同时在for之前必须给循环控制变量控制变量赋值,形式为:
    <初始表达式>;
    for(;<条件表达式>;<循环表达式>)
    <循环体语句>
  • <条件表达式>一般不能省略,否则为无限循环
  • 3个表达式均省略,即for( ; ; ;),为无限循环,程序中要避免这种事情发生。

二、while与do-while语句

1、while语句的一般形式:


while(<条件表达式>)
{
循环语句
循环变量表达式
}

2、while语句的重要特征

  • 环变量表达式>用来更新计算循环变量的值,一般情况下,<循环体语句>应该是用一对花括号括起来的复合语句,其中至少要有两条语句。
  • 若<循环体语句>中没有<循环变量表达式>,而只有循环语句,则有可能会使程序出现无限循环而发生错误。
  • 由于while循环是先判断<循环表达式>的值,后决定是否执行<循环体语句>,因此,<循环体语句>有可能一次也没有执行。
  • 在一般情况下,for和while可以互相转换

3、do-while语句的一般形式:


do
{
<循环体语句>
}while(<条件表达式>);

4、do-while语句的特征

  • 一般情况下,一定要有可以使<条件表达式>的值为假的语句,否则会使程序出现无限循环
  • do-while语句中的<循环体语句>的执行不同于for和while语句,它的<循环体语句>会先执行一次,因为是先执行<循环体语句>,后判断<条件表达式>。
  • 在某些情况下,while和do-while可以互相转换

三、break语句与continue语句

1、break语句既可用于分支结构,又可用于循环结构,其作用是跳出控制结构语句。
2、continue语句不会终止循环,而是在<循环体语句>没有执行完的情况下,结束当前循环,提前进入下一循环。

课后反思

一、对于上课时的i=i++问题的解决

1、实验代码如下:

#include<stdio.h>
main()
{
    int i=1,sum=0;
    while(i<=100)
    {
        sum=sum+i;
        i=i++;
    }
    printf("sum=%d
",sum);
}

??在编译的时候,程序并不会报错,理应在运行的时候出现的结果为“sum=5050”,但是,运行后结果如下:

技术图片

??为此,我问了几个朋友以及查阅大量资料,我的理解如下。

2、i++不能做左值?

(1)首先说左值和右值的定义:
??变量和文字常量都有存储区,并且有相关的类型。区别在于变量是可寻址的(addressable)对于每一个变量都有两个值与其相联:
??1).它的数据值,存储在某个内存地址中。有时这个值也被称为对象的右值(rvalue,读做are-value).我们也可认为右值的意思是被读取的值(read value)。文字常量和变量都可 被用作右值。
??2).它的地址值——即存储数据值的那块内存的地址。它有时被称为变量的左值(lvalue,读作ell-value)。我们也可认为左值的意思是位置值location value文字常量不能被用作左值.

(2)首先对于i++的实现是:
int temp;
temp = i;
i = i+1;
return temp;
而++i的实现是:
i = i+1;
return i;
所以对于我们提出来的问题已经能得到解决了:
??i++=5; 是错误的是因为i++返回的是编译器自动分配的临时变量temp,而这个temp并不是你程序中定义的可寻址变量的引用 ,也就是说你不能通过地址对它进行操作.(换句话说就是不能作为左值)++i=5;是正确的就是因为其返回值就是i;

3、用实验代码来解释
代码如下:

#include<stdio.h>
main()
{
    int i=0;
    i=i++;
    printf("i的值为%d
",i);
}

技术图片

??根据我们通常所知道的后自增先使用后增加的道理,i++在使用后i自身会增加一个数值,初始值为0时,自增后就是1,那么输出的结果应该是1.但实际上这题的结果却是0。

??这是因为开发工具在处理i = i++时, 会建立一个临时变量来接收i++的的值,然后返回这个临时变量的值,返回的值再被等号左边的变量接收了,这样就是说i虽然自增了但是又被赋值了0,这样输出的结果自然就是0了。
??不妨我们用temp临时变量来接收i++的值,来看一下结果。

#include<stdio.h>
main()
{
    int i=0;
    int temp;
    temp=i++;
    printf("i的值为%d
",i);
    printf("temp的值为%d
",temp);
} 

技术图片

??可以看到temp的结果就是0,也就是说赋值号右边传递过来的是i未自增前的值,这符合后自增运算符先使用后增加的原则,这时候我们再输出一下i的值。
i也的确自增了一个值,这样就好理解为什么i = i++中输出第一个i为什么是0了,因为i在自增后又被等式右边的值覆盖了。也就是说这里的i的值发生了三次变化,第一次是我们定义i = 0;第二次就是i自增后变成了1;第三次就是i又被0值覆盖了。

4、总结

??其实i++或者++i,只有单句的话执行是add加法运算,如果i++有赋值动作的话类似于下列代码:
int result,temp;
int i=0;
temp=i;
result=temp+1;
i=result;
i=temp;
??简单说其实i=0;i=i++就是i=1然后i=0,其实i++这个i就已经变成了+1的结果了,但是呢加完后回写了没运算的值。
??所以说,在上课那个例子中i总是等于1,满足i<=100,while永远为真,使得while无限循环,电脑内存不够,"炸了“。根据i++不能做左值,++i能做右值,来看,代码如下都可以使程序运行。

#include<stdio.h>
main()
{
    int i=1,sum=0;
    while(i<=100)
    {
        sum=sum+i;
        i=++i;
    }
    printf("sum=%d
",sum);
}

或者

#include<stdio.h>
main()
{
    int i=1,sum=0;
    while(i<=100)
    {
        sum=sum+i;
        i++;
    }
    printf("sum=%d
",sum);
}

技术图片

二、课本案例详解

1、例题中的几何图案

技术图片

??之前我们学了一些几何图形的输出,例如直角三角形,等腰三角形的输出等。但是,这个不同于之前的图形,这个比之前的更复杂。我的思路是:将这个图形先补齐,再分块。

技术图片

技术图片

??因为之前我们所输出图形的代码都是一个for中嵌套两个for,所以我总想着这样做完

#include<stdio.h>
main()
{
    int i,j,k,l,m;
    for(i=1;i<=5;i++)
    {
        for(j=1;j<=5-i;j++)
        printf(" ");
        for(k=1;k<=5;k++)
        printf("*");
        printf("
");
        for(l=1;l<=i-5;l++)
        printf(" ");
        for(m=1;m<=5;m++)
        printf("*");
        printf("
");       
    }
} 

技术图片

??我发现这和我预想的结果不一样,我再次分析了这张图。四个部分,第一个部分由空格组成;第二个部分由" * "组成,第三个部分由空格组成;第四个部分由" * "组成。想起老师课上讲的大循环里面是控制行,小循环里面控制了列。再反观自己的代码,我的代码大循环没有错。

#include<stdio.h>
main()
{
    int i,j,k,l,m;
    for(i=1;i<=5;i++)
    {
        for(j=1;j<=5-i;j++)
        printf(" ");
        for(k=1;k<=5;k++)
        printf("*");
        printf("
");
    }
} 

技术图片

??我发现,我前两个部分没有错,错的是后两个部分,使得我图案不能正常输出,我觉得要将第三第四个部分放在另外一个for的大循环之中,就像下面代码所示。

#include<stdio.h>
main()
{
    int i,j,k,l,m,n;
    for(i=1;i<=5;i++)
    {
        for(j=1;j<=5-i;j++)
        printf(" ");
        for(k=1;k<=5;k++)
        printf("*");
        printf("
");       
    }
    for(n=1;n<=4;n++)
    {
        for(l=1;l<=n;l++)
        printf(" ");
        for(m=1;m<=5;m++)
        printf("*");
        printf("
");           
    }

            
} 

运行结果如下:

技术图片

??但是,我还发现了另外一种方法来输出这个图案,虽然可行但是偏移了我们的本意。代码如下:

#include<stdio.h>
main()
{
    int i,j,k,l;
    for(i=1;i<=5;i++)
    {
        for(j=1;j<=5-i;j++)
        printf(" ");
        printf("*****");
        printf("
");
    }
    for(l=1;l<=4;l++)
    {
        for(k=1;k<=l;k++)
        printf(" ");
        printf("*****");
        printf("
");
    }
} 

技术图片

??总结一下,我觉得做这种图形的题目,首先要补齐图形,再划分图形,然后再敲代码。需要注意的是,for循环里面的<初始表达式>和<条件表达式>,因为这两个决定你的图形形状。

2、希望拓展的部分
??我希望老师可以穿插地讲一点关于程序设计中后面涉及到的问题,让我们更好地学习,例如:栈和堆,计算机的储存结构和代码的存放地址等,这样也可以让我们下课去查,为以后的学习减轻负担。

以上是关于第五章 循环结构课后反思的主要内容,如果未能解决你的问题,请参考以下文章

第五章 循环结构课后反思

第五章循环结构课后反思

第五章 循环结构课后反思

第五章 循环结构课后反思

第五章 循环结构课后反思

第五章循环结构课后反思