子程序怎么编程

子程序怎么编程,第1张

编写子程序的步骤如下:

1、先在头脑中想清楚子程序的功能,并理清子程序的前置条件、后置条件。2、给子程序起一个好的名字。这是一个好子程序的标志。3、写测试用例。4、编写并优化伪察老代码。书写伪代码时不应该出现具体语言的方法元素;编写伪代码时,也站在一个比较高的层次,比较详细的书写。5、将伪代码转化成具体语言的语句。

6、子程序书写完后,首先也是最重要的就是先在自己的脑海中执行子程序,检查子程序的所有可能执行路径、端点和所有异常条件。通常这一过程可以发现绝大部分的错误。7、编译子程序。在编译的过程中将编译器的警告级别调到最高,并注意编译器产生的每个警告信息。8、在调试器逐行执行子程序9、执行单元测试。在高没空这个过程中也用到第3步所写的测试用例。10、修改测试发现的问题,如果发现问题很多,则不修改子程序,而是直接重写子程序。11、检查子程序是否符合软件过程的一些基本思想。比戚瞎如耦合度、变量的命名、语句的布局、注释等。

一个标准的循环程序应由以下四部分组成:循环准备、循环体、循环修改、循环控制。

循环准备是为循环做准备的,有循环次数和起始地址;循环体是循环程序解题所需的核心程序,题目要完成的功能在此进行;循环修改用来更新某些数据或修正循环控制的参数;循环控制是循环是否结束的控制。

如果在一个程序中察弊的多个地方、或多个程序中的多个地扰没蠢方要用同一段程序,那么可以将这段程序单独设计,存放在某一存储区域,每当需要执行这段程序时,就调用指令转到这段程序去,执行完毕,再返回原来的程序。这段独立出来的程序叫做子程序或过程,调用它的程序称为主程序。采用子程序。使得设计结构清楚,程序的缓陪维护方便。当主程序需要执行这个子程序功能时,通过调用该子程序,执行子程序,子程序完成后返回主程序调用处,继续主程序后面的指令的执行。与子程序有关的指令有子程序的调用CALL、子程序返回RET两条指令。

1、调用子程序的含义:

在过程和函数的学习中,我们知歼袭道调用子程序的一般形式是:主程序调用租尺子程序A,子程序A调用子程序B,如图如示,这个过程实际上是:

@当主程序执行到调用子程序A语句时,系统保存一些必要的现场数据,然后执行类似于BASIC语言的GOTO语句,跳转到子程序A(为了说得简单些,我这里忽略了参数传递这个过程)。

@当子程序A执行到调用子程序B语句时,系统作法如上,跳转到子程序B。

@子程序B执行完所有语句后,跳转回子程序A调用子程序B语句的下一条语句(我这又忽略了返回值处理)

@子程序A执行完后,跳转回主程序调用子程序A语句的下一条语句

@主程序执行到结束。

做个比较:我在吃饭(执行主程序)吃到一半时,某人叫我(执行子程序A),话正说到一半,电话又响了起来(执行子程序B),我只要先接完电话,再和某人把话说完,最后把饭吃完(我这饭吃得也够累的了J)。

2、认识递归函数

我们在高中时都学过数学归纳法,例:

求 n!

我们可以把n!这么定义

也就是说要求3!,我们必须先求出2!,要求2!,必须先求1!,要求1!,就必须先求0!,而0!=1,所以1!=0!*1=1,再进而求2!,3!。分别用函数表示,则如图:

我们可以观察到,除计算0!子程序外,其他的子程序基本相似,我们可以设计这么一个子程序:

int factorial(int i){

int res

res=factorial(I-1)*i

return res

}

那么当执行主程序语句s=factorial(3)时,就会执行factorial(3),但在执行factorial(3),又会调用factorial(2),这时大家要注意,factorial(3)和factorial(2)虽然是同一个代码段,但在内存中它的数据区是两份!而执行factorial(2)时又会调用factorial(1),执行factorial(1)时又会调用factorial(0),每调用一次factorial函数,它就会在内存中新增一个数据区,那么这些复制了多份的函数大家可以把它看成是多个不同名的函数来理解;

但我们这个函数有点问题,在执行factorial(0)时,它又会调用factorial(-1)。。。造成死循环,也就是说,在factorial函数中,我们要在适当的时候保证不再调用该函数,也就是不执行res=factorial(I-1)*i这条调用语句。所以函数要改成:

int factorial(int i){

int res

if (I>0) res=factorial(I-1)*ielse res=1

return res

}

那么求3!的实际执行过程如图所示:

3、如何考虑用递归的方法来解决问题

例:求s=1+2+3+4+5+6+……+n

本来这个问题我们过去常用循环累加的方法。而这里如要用递归的方法,必须考虑两点:

1) 能否把问题转化成递归形式的描述;

2) 是否有递归结束的边界条件。

设:函数s(n)=1+2+3+…+(n-1)+n

显然递归的两个条件都有了:

1) s(n) =s(n-1)+n

2) s(1)=1

所以源程序为:

int progression(int n){

int res

if (n=1 )res=1 else res=progression(n-1)+n

return res

}

4、递归的应用

中序遍历二叉树

void inorder (BinTree T){

if (T){

inorder(T->lchild)

printf(“%c”,T->data)

inorder(T->rchild)

}

}

现假设树如图(为了讲解方便,树很简单)

@执行第一次调用inorder1,T指向顶结点,T不为空,所以第二次调用inorder2;

@T指向顶结点的左子树结点也就是B,不为空,所以第三次调用inorder3;

@T指向B结点的左子树结点,为空,所以什么都不执行,返回inorder2;

@打印B结点的DATA域值“b”;

@第四次调用inorder4,去访问B子树的右结点

@T指向B结点的右子树结点,为空,所以什么都不执行,氏型兄返回inorder2;

@返回inorder1;

@打印A结点的DATA域值“a”;

@第五次调用inorder5,去访问A子树的右结点;

@T指向A结点的右子树结点,为空,所以什么都不执行,返回inorder1;

@inorder1执行完毕,返回。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/12364872.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-24
下一篇 2023-05-24

发表评论

登录后才能评论

评论列表(0条)

保存