2.10 自定义函数
前面,已经使用了NSLog()函数来显示信息,接下来,我们看一看如何创建自己的函数,而这些函数可以帮助我们更好地组织代码和实现软件功能。
函数是一种基本的代码封装与组织形式,我们知道,在一艘军舰上,只有各个岗位的人员都能够各尽其责,军舰才能够正常运行,才会有战斗力。而函数对于整个程序来讲,也是这样,必须能够正确、高效地完成本职工作才称得上是一个合格的函数。
从图2-16中,我们可以看到,程序会从main()函数开始,然后会有大量的函数来支援它,这就是函数的基本工作方式。目前为止,我们使用的示例项目都是这种工作方式。此外,在Objective-C中,我们还可以使用另一种代码组织形式,这就是使用面向对象编程(OOP),在第4章,我们会讨论相关内容。
图2-16 函数的调用
在Objective-C中声明函数的格式如下。
<返回值类型> <函数名>(<参数列表>);
如果我们实现这个函数,就不使用分号,而是将函数的代码放在一对花括号{}之间。如下面的代码。
#import <Foundation/Foundation.h> void sayHello() { NSLog(@"Hello! "); } int main(int argc, const char *argv[]) { @autoreleasepool { sayHello(); } return 0; }
代码中,我们定义了一个无返回值、无参数的sayHello()函数,然后,在main()函数中调用它;执行代码会显示“Hello! ”。
接下来,我们讨论一下定义函数时需要注意的几个问题。
■2.10.1 返回值类型
返回值类型,也就是函数运行结果的数据类型;在函数中,使用return语句返回这个数据;如果函数不需要返回数据,就像上面的代码一样,可以将返回值类型定义为void。
返回值的类型可以是前面介绍的基本数据类型,也可以是对象,比如,函数需要返回一个字符串对象(NSString类型),还应该使用*运算符。如下面的代码。
NSString* getName() { return @"你猜!^_^"; }
关于对象的相关内容,我们会在第4章介绍,大家不用着急。
■2.10.2 函数名
函数的名称,本书中的自定义函数名会使用首字母小写,其他单词首字母大写的形式。
函数名应该反映出函数的功能,在Objective-C中,函数命名会有一些约定,遵循这些约定,可以更有效地使用这些函数,在后续的应用中,我们就可以看到这一点。
■2.10.3 参数
参数列表,在定义函数时,可以没有参数,像上面代码中定义的sayHello()函数,也可以有一个或多个参数,每一个参数都应包含两个基本部分,即参数类型和参数变量,如下面的代码。
#import <Foundation/Foundation.h> int addInt(int x, int y) { return x + y; } int main(int argc, const char *argv[]) { @autoreleasepool { int sum = addInt(6, 4); NSLog(@"sum = %i", sum); } return 0; }
在我们定义的addInt()函数中,定义了两个参数,分别是x和y,它们都是int类型的,而addInt()函数的功能就是返回这两个参数的和,其返回值类型同样是int类型。
■2.10.4 参数指针
下面,我们创建一个函数,尝试交换两个int变量的值,这个看上去似乎并不难,马上动手,如下面的代码。
void swapInt(int x, int y) { int temp = x; x = y; y = temp; }
然后,使用如下代码来调用这个函数。
int main(int argc, const char *argv[]) { @autoreleasepool { int num1 = 10; int num2 = 99; NSLog(@"num1 = %i , num2 = %i", num1, num2); swapInt(num1, num2); NSLog(@"num1 = %i , num2 = %i", num1, num2); } return 0; }
问题来了!上面的代码并不会交换num1和num2的值。
这是为什么呢?
原因是,当我们将num1和num2变量传递给swapInt()函数时,参数复制了它们的数据。在函数内部,只是在交换数据副本的值,而不是真正地交换num1和num2变量的值。
那么,如何才能真正地修改参数的值呢?答案就是,在参数中使用指针,下面就是修改后的swapInt()函数。
void swapInt(int *x, int *y) { int temp = *x; *x = *y; *y = temp; }
在调用swapInt()函数时,我们同样需要做一些修改,如下面的代码。
swapInt(&num1, &num2);
这样,我们就可以通过swapInt()函数顺利地交换两个int变量的值了。