Objective-C和Sprite Kit游戏开发从入门到精通
上QQ阅读APP看书,第一时间看更新

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变量的值了。