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个三角数的值并显示答案。