首页 理论教育过程在计算机导论中的作用

过程在计算机导论中的作用

【摘要】:我们在7.2节中曾指出,过程是算法的基本元素,过程可以使一个求解大问题的算法分解为若干个求解子问题算法的有机合成。过程的参数是局部变量。如图7-6所示,过程调用时,实参拷贝数值6给虚参,若过程运行时虚参的数值改变为8,则过程结束后主程序中实参的数值还是原来的6,而不是8。

我们在7.2节中曾指出,过程是算法的基本元素,过程可以使一个求解大问题的算法分解为若干个求解子问题算法的有机合成。高级语言在实现过程时,要考虑过程的调用、过程的参数、过程的返回、参数的传递方式等问题。

1.过程的调用

过程主要有两个用途:

(1)构造通用的算法模块;

(2)把一个大的、复杂的算法分解为若干个小的、简单的算法的合成。

过程的这两种用途都涉及一个程序对一个过程的调用。所谓过程的调用,是指停止执行当前的程序,而转去执行被调用的过程。过程的调用如图7-4所示。

在图7-4中,主程序表示当前正在运行的程序。在主程序的运行过程中,如果遇到调用过程的语句,则停止运行当前的主程序,而转去运行被调用的过程。过程运行完后,再返回到主程序调用过程语句的下一条语句继续运行。

图7-4 过程的调用

由图7-4所示的过程的调用可知,高级语言中必须包含一条过程调用语句。过程调用语句要给出被调用的过程名。不同高级语言的过程调用语句格式不同。下面给出C语言和PASCAL语言的过程调用语句示例,例子中的Sum3表示被调用的过程名,为使问题简单,假设该过程没有参数:

C语言 PASCAL语言

Sum3; CALL Sum3

2.过程的参数

通常过程都包含有参数,过程的参数使过程的设计具有灵活性和通用性。例如,求1~n的累加和问题的C语言函数(C语言把过程称作函数)如下:

int Sum1(int n)

{

inti,sum; //变量定义

sum =0; ∥累加初始化

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

sum =sum +i; ∥循环累加

return sum; //返回语句

}

上述C语言函数可以求1~n的累加和问题,其中,n可以是任意的整数数值。这样,高级语言过程的参数就必须是变量,该变量的具体取值由调用该过程的主程序给出。主程序通过传送具体的数值给被调用过程的参数,来实现具体的过程调用。

过程的引入就使程序可以由多个模块组成,这些模块在具体设计时可能由多个不同的人来完成。为了防止一个过程内的变量数值被起了相同变量名字的其他过程混用,高级语言把变量分为全局变量和局部变量。全局变量是允许所有模块都使用的变量,局部变量是只允许在一个过程体内使用的变量。

过程的参数是局部变量。例如,上面例子中的参数n是局部变量。

3.过程的返回

从图7-4可知,过程的调用包含调用和返回两个步骤。调用步骤要求主程序传送具体数值给过程,然后通过过程的参数来实现。返回步骤要求把过程的计算结果传送给主程序。

由于变量分作局部变量和全局变量,为避免一个过程被外部的程序非法修改,高级语言规定:在一个过程内定义的变量都是局部变量。例如,上述例子中过程内定义的变量sum就是局部变量。我们说过,外部于过程的主程序是无法得到过程内局部变量的数值的,所以要考虑把过程计算结果传送给主程序的方法。这样的处理方法主要有两种。这里我们讨论第一种方法。第二种方法将在讨论参数的地址传送方式时介绍。

高级语言处理过程返回的第一种方法,是把过程名既看作过程名,也看作一个变量。这样,只要我们首先把过程名这个变量定义成全局变量,然后把过程的计算结果传送给过程名,在主程序中就可以得到计算结果。

不同的高级语言实现把过程的计算结果传送给过程名的方法不同。在C语言中,设计了一个专门语句用来实现把过程的计算结果传送给过程名,该语句的格式如下:

returnx;

其中,return是该语句的标识符,x表示要传送给过程名的计算结果变量名。例如,上述例子中,过程的最后一条语句“return sum;”就是用来实现把计算结果sum中的数值传送给过程名Sum1。

4.参数的传递方式

主程序通过给被调用过程的参数传送具体的数值来实现过程的调用。主程序和被调用过程之间通过参数传送数据有两种方法。(www.chuimin.cn)

通过参数传送数据的第一种方法称为值传送。所谓值传送,就是把主程序调用过程的具体数值(称为实际参数,或简称实参)拷贝给过程的参数(称为虚拟参数,或简称虚参)。图7-5(a)就是值传送方式实现方法的示意。其中,实参和虚参都是内存单元,在过程调用时,把实参中的数值拷贝给虚参。

通过参数传送数据的第二种方法称为地址传送。所谓地址传送,就是把虚参表示成内存单元地址形式,此时虚参指向的内存单元和实参指向的内存单元相同,或者说,虚参和实参共享一个内存单元。图7-5(b)就是地址传送方式实现方法的示意。

图7-5 参数的传递方式

(a)值传送;(b)地址传送

参数的传递方式对程序实现的方法有一定的影响。对于值传送来说,由于数据的传送是单方向的,即只有从主程序到过程一个方向,所以,如果运行过程时,参数的数值发生了改变,将不会影响到主程序中原来的数值。如图7-6所示,过程调用时,实参拷贝数值6给虚参,若过程运行时虚参的数值改变为8,则过程结束后主程序中实参的数值还是原来的6,而不是8。

图7-6 值传送方式的单向性

(a)调用时;(b)运行时;(c)结束时

对于地址传送来说,由于虚参和实参实际上是同一个内存单元,所以,可以认为数据的传送是双方向的。此时,虚参数值的任何改变都会影响到实参的数值。如图7-7所示,过程调用时,实参的数值为6,则虚参的数值也为6,若过程运行时虚参的数值改变为8,则过程结束后主程序中实参的数值也就是8,而不是原来的6。

图7-7 地址传送方式的双向性

(a)调用时;(b)运行时;(c)结束时

参数的地址传送方式可以把过程的计算结果带回到主程序中。前面我们说过,高级语言处理过程返回的第一种方法,是让定义为全局变量的过程名把过程的计算结果带回到主程序中。有些复杂问题的计算结果有若干个,而过程名却只能带回一个计算结果。参数地址传送方式的双向性,提供了过程返回的第二种方法。我们可以把需要带回主程序的计算结果设计成地址传送方式的虚参,这样,在过程运行完后,主程序就可以从相应的实参得到过程的计算结果。

5.过程调用示例

这里给出一个求1~n的累加和问题的完整C++语言程序,以此来说明高级语言过程调用的实现方法。C++语言程序如下:

int Suml(int n) //过程定义

{

int i,sum;

sum=0;

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

sum=sum+i;

return sum;

}

#include<iostream.h>

void main(void) //主程序

{

int n,sum;

cout<<″输入数值n:″,

cin>>n; //输入n

sum=Sum1(n); /过程调用

cout<<″sum=″<<sum<<endl; //输出sum

}

过程定义部分既定义了过程Suml的具体实现,也定义了过程名Suml是一个全局变量。主程序是以名字为main开始的部分,主程序中首先要求用户输入实参n的具体数值(假设用户输入100),然后以实参n=100调用过程Suml,过程Sum1完成1~n的累加计算后,语句“return sum”实现把局部变量sum中保存的计算结果(数值为5050)传递给过程名Sum1,最后返回主程序继续运行。因为过程名Sum1是一个全局变量,所以主程序中可以读取该变量中的数值。主程序中把全局变量Suml中保存的计算结果(数值为5050)再赋值给主程序中的局部变量sum,最后主程序输出局部变量sum中的数值后结束程序运行。