13.2 函数

到目前为止,每个程序中接触到的NSLog例程就是一个函数例子。事实上,每个程序还用到一个名为main的函数。回顾你编写的第一个程序(代码清单2-1),它在终端显示“programming is fun.”这个短语:


import<Foundation/Foundation.h>

int main(int argc, char*argv[])

{

NSAutoreleasePool*pool=[[NSAutoreleasePool alloc]init];

NSLog(@“Programming is fun.”);

[pool drain];

return 0;

}


下面是名为printMessage的函数,它产生同样的结果:


void printMessage(void)

{

NSLog(@“Programming is fun.”);

}


函数printMessage和代码清单2-1 main函数的唯一区别在第一行。第一行函数定义告诉编译器关于该函数的4件事情:

·谁可以调用这个函数;

·函数的返回值类型;

·函数的名称;

·函数使用的参数数目和类型。

函数printMessage的第一行告诉编译器printMessage是这个函数的名称,并且该函数不返回任何值(第一个void关键字的用途)。与方法不同,不必将函数的返回值类型放在一对圆括号中。事实上,如果这么做,将得到一条编译错误消息!

告知编译器printMessage不返回任何值之后,第二个void关键字的用途说明该函数没有任何参数。

回忆一下,在Objective-C系统中,main是一个特别的名称,它总是指示程序开始运行的位置。每个程序都必须有一个main函数。所以,可以向前面的代码添加一个main函数,以完成这个程序,如代码清单13-3所示。

代码清单13-3


import<Foundation/Foundation.h>

void printMessage(void)

{

NSLog(@“Programming is fun.”);

}

int main(int argc, char*argv[])

{

NSAutoreleasePool*pool=[[NSAutoreleasePool alloc]init];

printMessage();

[pool drain];

return 0;

}


代码清单13-3输出


Programming is fun.


代码清单13-3包含两个函数:printMessage和main。前面提到过,调用函数并不是新的概念。因为printMessage不带有参数,所以可以简单地在名称后面添加一对左右圆括号来调用它。

13.2.1 参数和局部变量

在第5章“循环结构”中,开发了一个用于计算三角数的程序。这里你将定义一个产生三角数的函数,并且恰当地将其命名为calculateTriangularNumber。通过该函数的一个参数,指定要计算哪个三角数。然后这个函数计算出所求的数值并显示结果。代码清单13-4显示了完成这项任务的函数和测试它的main例程。

代码清单13-4


import<Foundation/Foundation.h>

//Function to calculate the nth triangular number

void calculateTriangularNumber(int n)

{

int i, triangularNumber=0;

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

triangularNumber+=i;

NSLog(@“Triangular number%i is%i”,n, triangularNumber);

}

int main(int argc, char*argv[])

{

NSAutoreleasePool*pool=[[NSAutoreleasePool alloc]init];

calculateTriangularNumber(10);

calculateTriangularNumber(20);

calculateTriangularNumber(50);

[pool drain];

return 0;

}


代码清单13-4输出


Triangular number 10 is 55

Triangular number 20 is 210

Triangular number 50 is 1275


函数calculateTriangularNumber的第一行是


void calculateTriangularNumber(int n)


它告知编译器calculateTriangularNumber是一个函数,它不返回任何值(关键字void)并且带有一个名为n的int参数。再次注意,不能像编写方法那样,将参数类型放在圆括号中。

左花括号表示函数定义的开始。因为你想要计算第n个三角数,所以必须设置一个变量,以便在计算过程中储存三角数的值。还需要一个变量作为循环的索引。为此,定义了变量TriangularNumber和i,并将其声明为整型变量。这些变量的定义及初始化方式和在前面程序的main函数中定义和初始化变量的方式相同。

函数中局部变量的行为同方法中的一样:如果在函数内给变量赋予初始值,那么每次调用该函数时,都会指定相同的初始值。

在函数中(和在方法中一样)定义的变量称为自动局部变量,因为每次调用该函数时,它们都自动“创建”,并且它们的值对于函数来说是局部的。

静态局部变量用关键字static声明,它们的值在函数调用的过程中保留下来,并且初始值默认为0。

局部变量的值只能在定义该变量的函数中访问。它的值不能从函数之外访问。

回到我们的程序示例,定义局部变量之后,该函数计算三角数并且在终端显示结果。右花括号表示函数结束。

在main函数中,数值10是在第一次调用函数calculateTriangularNumber时作为参数传递的。然后,执行直接转换到该函数,数值10成为函数中形参n的值。然后,该函数计算出第10个三角数的值并显示结果。

再次调用函数calculateTriangularNumber时,传递参数20。经过与前面描述相似的过程,该数值成为函数中n值。然后,该函数计算出第20个三角数的值并显示答案。