[音乐] 大家好,这一讲我们来学习程序控制结构
我们说,任何计算问题,实际上都可以被描述为按照一定的顺序去执行一系列的操作
那么也就说,任何计算问题实际上都是一个求解过程 这个过程包括要执行的动作,以及执行这些动作的顺序
所以,这里的这个求解过程,我们就称为算法 算法在整个软件设计中,是非常非常重要的
一种思路或者一种方法,也就说它实际上是 你希望利用计算机语言去解决问题
必须要首先建立的一种思路 这种思路的描述其实就是算法。
我们随便可以举一个例子来说明一下这个算法的重要性
比如现在有一大堆的数据,这些数据杂乱无章,我们现在
希望做这么一项工作,我们把这一堆数据由小到大排列成顺序 那么完成这样一个工作你首先要做什么呢?
你当然你说我可以这样啊,我先在里头先去找找找,找到一个最小的值 放在,排到第一。
然后呢在剩下的数里头,我再去找一个排到第二 以此类推,这样子排下去。
这样子肯定能够把这些数排列得整齐 假设这个数一共有10000条,那么我们就可以做
哦,通过这样子一步一步的完成,我们最后把这10000个数据都排列完了
那么排好了,对这样,用这样子的方法完成了这样子的一个排序
那么我们需要花多少时间呢?这个时间的数量 级,注意这里说的是数量级,而不是准确的分和秒
这个数量级大概是10000乘10000这样子的数量级,也就是说10的8次方
那么我们还可以用另外一种办法 假设我们在这个10000个数里边,我们先随便抓一个数出来,把它作为一个关键数
然后呢,我们第一次,我们把所有比这个关键数小的数,都放在这个关键数的前边
然后把比这个关键数大的那个数都放在它的后边
这样我们完成一次操作以后,那么这个关键数就位于整个10000个数的最中间
之后呢我们把前一半用同样的方法做,后一半也用同样的方法
做,所以这样子的最后呢,我们很快的把这10000个数的顺序排好了
这种方法我们叫做快速排序,那对这种快速排序 对10000个数要做这样的排序,需要的时间数量级大概是多少呢?
大概是100乘10000这样的数量级,那么随着这样的 数据的多,或者这个程序语句的规模的增多
那么这两种方法它们在时间的消耗上会差的很远
所以这就是我们说你算法设计的好与不好经常会影响你整个程序的运行效率
好了,那么我们程序正常情况下都是按着 我们自己编写的时候的顺序,一行一行语句执行下去的
那么有时候呢实际上我们并不希望这样做 假设我们现在做一个加法运算,100个数的
求和,那么实际上我们每一次反复地来回做的都是加法 可是我们每一次加的数据是不一样的。
所以我们其实可以用一行加法语句 然后呢不断地去修改加数和被加数的值
也就说不断地重复去执行这样的一个加法指令,加法语句 那么我们这个工作也能完成。
所以这样子的话,我们的程序就可能有两种方式:一种是
我们每一行语句都是求和,也就是说我们要100个数的话,我们要写100个加法语句
那么还有一种呢,我们只需要写一行加法语句, 只是每一次改变它不同的数据而已
这两种方法在程序的规模上我们会发现它差距非常大
嗯,那么不同,不停地去重复 这个工作我们叫做循环的工作。
所以程序中语句的执行顺序 是可以通过某一种方法去改变的
也就是说我们本来一行语句执行完,执行下一行,这下一行完了以后再下一行 这种顺序执行下去。
这是从本能上或者说从惯性上程序是这样执行的 但是我们可以通过某一种办法改变这种顺序。
也就是说,第一行执行完我们不一定去执行第一行,我们可能去执行第100行
这种工作叫程序控制,那么实现这样程序控制的语句 就叫程序控制语句。
那么所以程序控制语句的作用就是控制程序的走向 说或者控制中程序语句的执行顺序。
好,下边我们在这一讲里 我们并不想给大家详细地去讲每一种程序控制语句
这些每一条控制语句,我们将在后续的课程中慢慢地去学习
在这一讲里头,我们先介绍给大家主要的几种 程序控制结构。
总体上来讲,程序的控制结构一共有三种
一种我们称为顺序结构,一种称为选择结构,也称为分支结构 还有一种循环结构。
所有的程序都可以有这三种 结构,通过各种的组合,嵌套来构成
所以这三种结构可以组成任何复杂的程序结构 那么什么是顺序结构呢?顺序结构就是刚才
我们说的第一行语句执行完就第二行,第二行执行完就第三行 就像这个图里头所描述的那样,一行语句一行语句的顺序执行下去
那么当然还有一种理念,就说我们程序实际上是一个一个的 程序模块来组成的,那么顺序的结构也可以描述成这样
就第一个程序模块执行完,接着执行第二个程序模块,一直以此类推下去
那么这几个程序模块可能又可以组合成一个新的程序模块。
哦 新的程序模块变成了一个,一个整体 然后它执行完可能再会执行新的程序模块 这样子就说顺序结构。
所以总而言之,所谓的顺序 就是按照我们程序设计编写的顺序
一行一行的执行下去,这就是顺序结构。
我们来看一个简单的顺序结构的例子
首先我们输入a和b,然后呢我们来
把a赋值给一个变量t 然后呢我们把b再赋值给a
然后呢我们再把t赋值给b 最后输出a和b。
那么这就是一个顺序结构的一个算法的描述 哦,这种描述呢,有关算法的详细的概念,我们后续课程里再给大家介绍
那么这是算法的一种表示方法。
哦,这里边最起始的那个带圆弧的矩形 框一般是代表着整个算法描述的开始和结束。
也就是说通常这两个框 并没有具体的处理的功能,它只是一种象征
这种平行四边形的框,我们通常用它来表示输入和输出 这种矩形框就代表着一个处理的功能。
我们后边还会看到 有菱形的框,我们到时候再说它的意思。
从这样一个流程里边 我们可以看到它的每一行每一行都是在前边执行完了以后就执行下边,执行下边以后再往下走
所以整个这个流程的功能表示什么意思呢?这个功能就是表示了a和b的互换,并且 输出。
这就是一个顺序结构的一个算法的描述。
一个非常经典的算法的描述 所谓选择结构就是程序按照某种设定的条件
两分支或者多分支的去执行,这个图里边大家可以
看到当条件满足的时候,我们会继续向下执行模块一
条件不满足的时候,它会走向右边去执行模块二 这个就是选择结构的一个形象的表示。
选择结构 相对于顺序结构来讲,它的品种稍微要多一些 在C#里头有三种类型的选择结构。
一种比如我们称为 if结构,也就是说当你的条件满足的时候,它执行某个动作
条件不满足的话,就跳过这个动作,就不执行了,就什么也不执行了。
那么还有一个叫if else 也就是说当你条件满足的时候执行某种动作 条件不满足的话,执行另外一个动作。
这就是两个分支的情况 还有一种叫switch结构,也就是说满足条件1,它执行一个
动作,满足条件2又去执行第二个动作,满足条件3又去执行第三个动作 等等。
它构成的是一个多分支的 或者说多选择的结构。
我们下边再来看这个图,单分支结构的表示方法是这样 if后边是一个表达式。
就当表达式的运算结果满足它的要求 的时候。
那么它会执行if后边的语句,否则就不执行
这个后边的语句可以是一行语句,也可以是一个用{}括起来的复合语句
那么这个两分支的结构的语句格式是这样 就说if表达式满足,那么会执行下边这条语句1
如果不满足,它会去执行语句二,这是同样的,语句序列一和序列二也可以是 分别是单行语句或者是复合语句。
这个两分支的结构我们可以用这个图来表示一下。
对于多分支的程序结构,我们在这里看是这样子的:就是说
当你满足一个条件执行语句一,满足第二个条件可能执行语句二,依次类推下去。
这个就是选择结构。
同样我们也用一个例来表示一下选择结构的这种算法描述。
这个我们希望来干什么么?希望来求一个多项式的一个值Y, 当这个X大于等于0的时候,我们说Y值要等于
2X加1;当X小于0的时候,我们说Y等于负X。
这种算法我们怎么样来表示呢,用流程来表示呢?这个流程,我刚才再补充一下,刚才这个流程
我们也简称,因为它是个图形的结构,所以我们也叫流程图。
下面我们用流程图来描述一下 求这个多项函数值Y它的算法描述。
首先,我们也用这样一个带圆弧的矩形框来表示开始,用平行四边形来表示输入,
那么这个输入一个X,下面要干什么?从这样一个函数值的
这个表达式里我们可以看出来,我们首先要判断这个X是大于等于0呢,还是小于0, 所以下边我们用菱形框来表示判断。
这个是流程图中间的,我们刚才顺序结构里没有看到的一个图符, 就是菱形,这个菱形表示一种判断的意思。
在这里,X大于等于0,我们往下走,就是成立的话,
我们就直接执行Y等于2X加1
如果X大于等于0不成立,也就是说X小于0 了,那么我们就走这一条路。
然后呢,两条路执行完了以后,不管是哪一条,这两路肯定只能
执行一条,对吧?执行完了以后,我们最后的结果要干什么呢?要把这个Y值输出。
所以下边我们是输出Y,最后就结束。
这就是分支结构,两分支结构的一个算法描述的示例。
好,下边我们来看一下循环。
所谓循环呢, 实际上说白了就是在不停地重复执行某一段程序,
或者说不停地重复一段相同功能的程序。
那么这种重复不能无限制地重复下去,所以在循环结构
里头一定要注意的一点,就是你必须要有一个循环结束的条件。
就像我们刚才选择结构里,不管是成立还是不成立,一定要有一个
条件,就是说X大于等于0这就是一个条件,X小于0这又是一个条件,
它总归要有一个计算值,就是要有一个你选择路径的一个结果。
但是在循环程序里头呢,我们要注意的就是怎么样构成一个 退出的条件,我不能无限期的在这里重复执行重复执行,那么这就
结束不了了,所以在循环程序里头,大家要关注的就是循环结束的条件。
循环程序结构用这个图可以表示, 这个图表示了什么呢?就是我们首先去判断它的条件满足还是不满足,
满足,我们就去执行这个循环体;不满足,就 直接退出来,这个叫先判定性的循环性程序;
还有一种呢,不管条件满足不满足,我们 都先把整个这个矩形框里的循环体先执行一遍再说,
执行完了以后,我们再去看,哎这个条件,现在的条件还满足 不满足,到点了没有,没到点再回去再执行,到点了就结束。
所以左侧这个叫做先判定性,右侧这个叫 后判定性,这两种我们都称为循环结构。
下边我们也来看一个循环结构的算法示例。
首先,我们这里是开始用圆弧,带圆弧的矩形框来表示 第二步是一个有具体功能的一个矩形框,它表示将0
赋值给一个变量MAX,第三步同样是一个功能框, 讲1赋值给变量I,第四步我们看到是一个
平行四边形,那么它表示数据的输入或者输出, 那么在这里,我们是说接收了一个输入的数据,并且赋值给X,
好,再下边,我们就是一个菱形框,这是一个用来表示判断的框,
在这样一个图符里头,我们看到是判断MAX是不是小于等于刚刚 输入的那个值X。
那么如果成立的话,那么也就是说X要比MAX大的话,
那么我们就把X赋值给MAX;那么如果不成立的话,那么也就说MAX比X大,
那么我们就继续,继续什么呢,继续把I再加1,I自增1。
之后,我们再去判断I有没有小于10,
如果是小于的,我们继续将刚才的那个动作再重复执行一遍,
如果说X不小于等于10了那么也就说它大于10了,那么这个时候整个程序就结束了,
将我们刚才的MAX,这个变量的值输出。
这个算法流程大家能够看得出来它的功能是什么吗?
我想应该是没问题的,对吧?这是一个在10个数中 找最大值的一个算法描述。
在这样一个算法流程图里头,我们看最里面
的这一层,实际上就是我们刚才前面学的那个选择结构,或者说两分支结构;
外面的这一层就是我们现在看到的循环结构。
在我们的大多数程序里头,我们的顺序结构,选择 结构和循环结构实际上都是并存的。
好,这三种基本程序的控制结构
就构成了我们今天所有复杂的程序结构,这种思想来自于结构化程序的设计思想。
结构化程序是在1965年所提出来的,它的主要思想 就是认为软件设计是自底向上,逐步求精
最后模块,并且是模块化设计这样子的一个方法。
它的提出主要是相对于之前非结构化程序设计所带来的各种软件危机
而提出来的,当然那些话说起来就比较多,不再是我们这门课的内容了。
所以在这里,我想跟大家讲,就是说结构化程序,和我们C#这种面向对象的程序设计,
那么它的不同点在哪里呢,呃,也有不少, 但是主要的一点,就是为什么要提出面向对象的程序设计方法,
就是面向对象的程序设计,是将所有的事物都认为是对象,而把
这些对象的属性和它的操作,也就是它各种对操作的数据等等,
都封装在了一起,这样子地带来的最大的一个好处就是便于程序的
可扩展性以及它的继承性,也就是说它能够 为更多的这种程序复用带来很多的方便。
而结构化程序在这一点上是比不上面向对象程序设计方法的。
那么你说 今天的C#语言已经是面向对象的程序设计方法,我们为什么还要来讲程序结构呢?
就是因为在不管面向对象的程序设计方法如何的炫,
但是在某一个具体的类里面,某一个具体的方法里,我们的程序代码依然是顺序、 循环、
分支这样三种结构所构成。
所以 这种结构化程序的设计思想我们还是需要了解的。
好,有关程序的控制结构我们就给大家描述在 这里。
下一讲我们将来给大家介绍具体的程序控制语句。
好,今天就到这里。
[空白音频]