7.5 局部变量

你也许注意到1/4和1/2相加的结果显示为6/8,而不是期望的3/4,这是因为加法例程只执行算术不做其他处理,它不会将结果相约。所以继续练习如何编写有关分数运算的新方法。编写一个新的reduce方法,将分数相约到它的最简形式。

回顾一下中学学过的数学课程,通过找到能同时整除分子和分母的最大数来约简分数,然后使用这个数除分子和分母。技术上,要找出分子和分母的最大公约数(gcd)。代码清单5-7已告知如何得到它。稍一回忆也许就会想起这个程序。

根据这些算法,可以编写出名为reduce的新方法:


-(void)reduce

{

int u=numerator;

int v=denominator;

int temp;

while(v!=0){

temp=u%v;

u=v;

v=temp;

}

numerator/=u;

denominator/=u;

}


注意这个reduce方法中有一些新东西:它声明了三个整型变量u、v和temp。这些变量是局部变量,意思是它们的值只在reduce方法运行时才存在并且只能在定义它们的方法中访问。从这个意义上来说,它们类似于在main例程中定义的变量;这些变量对main来说是局部变量,可以在main例程中直接进行访问。你定义的其他方法都不能访问main中的局部变量。

局部变量没有默认的初始值,所以在使用前要先赋值。reduce程序中有三个局部变量在使用之前被赋值,所以没有问题。和实例变量不同(它们通过方法调用赋值),这些局部变量不存在于内存中,也就是,当方法返回时,这些变量的值都消失了。每次调用方法,该方法中的局部变量(如果有的话)都使用变量声明初始化一次。

7.5.1 方法的参数

方法的参数名也是局部变量。执行方法时,通过方法传递的任何参数都被复制到局部变量中。因为方法使用参数的副本,所以不能改变通过方法传递的原值。这是一个重要概念。假设有个名为calculate:的方法,其定义如下:


-(void)calculate:(double)x

{

x*=2;

……

}


并假设使用以下消息表达式来调用它:


[myData calculate:ptVal];


执行calculate方法时,ptVal变量所含的任何值都被复制到局部变量x。所以改变calculate中x的值,对ptVal的值没有影响,只影响x变量的数据副本。

顺便提及,如果参数是对象,可以更改其中的实例变量值,我们在下一章中将了解更多内容。