上一章Objective-C开发教程请查看:Objective-C条件语句详解
前几章都是和C语言类似的,可以适当跳过,但是这章就不行了。这章我们讨论OC中的函数声明、定义函数、调用函数和函数参数,不过函数的功能还是一样的,函数是一个语句的集合,用于实现特定的逻辑功能。每个OC程序都有一个main入口函数,该函数的完整签名为:
int main(int argc, char** argc);
这种是C语言的方式,第一个参数表示传递的参数的个数,第二个参数表示参数数组,就是使用命令行执行程序时的参数。
但是OC不是使用C语言的风格,是一种魔幻的风格,简直太垃圾了!有人说OC的函数非常清晰,但是好鬼长的函数签名,相当之麻烦!不过函数的实质概念还是一样的,可以对照一下C中的一些概念。
首先函数声明告诉编译器函数的签名:返回类型、函数名和参数(和之前说的extern声明类似),声明可以有多个,函数定义是函数的实际实现,定义实现只能有一个。(OC一般称函数为方法,不过也都是一样的)
学完本节,你将可以使用Foundation框架中的函数了,也可以自定义一些函数。
函数声明
函数声明是告诉编译器有这个函数,区别一个惟一的函数是使用函数的签名,函数声明的语法如下:
- (返回类型) 函数名: (参数类型1)参数名1
name2: (参数类型2)参数名2 ...
name: (参数类型)参数名;
是不是好复杂?是吧,何苦呢…使用C风格不是很好么。首先我们解释一下上面函数声明的意思:
- –:表示这是一个对象函数/方法(必须由实例调用),也就是说不能在一个对象外部进行声明,在对象外部声明,可以使用extern关键字,但是不能使用“-”。在对象外部的方法使用C风格的函数进行声明,另外使用“+”表示这是一个类方法,直接使用类调用(不需要实例),类似于Java中的static静态方法。
- 返回类型:函数的返回值类型,如果没有指定返回类型,则默认为id类型,id是一个指针,类似于C中的void*。
- 函数名:函数的实际名称,但是仅仅是函数名并不是函数签名,函数签名包括返回类型、函数名和参数表,例如- (void)hello: (int)message user: (NSString*)user是一个函数签名。
- 参数:OC使用的是连接参数,每个参数前面都有一个名称name,后面指定参数的类型,以及使用的参数名。一般来说可以使用name语义化,然而并没有什么卵用——习惯上,不语义化可以直接将name和参数名设置为一样即可。
下面是一个函数声明的例子:
- (int) max: (int)a and: (int)b;
这种形式的函数声明一般都是用在头文件的声明中。
定义函数
定义函数的语法和声明函数的语法类型,但是有实际的实现,也就是函数体:
- (返回类型) 函数名: (参数类型1)参数名1
name2: (参数类型2)参数名2 ...
name: (参数类型)参数名{
函数体
}
下面是函数max:and:的实现,注意,和其它语言不同,不能直接说是max函数,而是max:and:函数。
- (int) max: (int)a and: (int)b{
int result;
if (a > b) {
result = a;
} else {
result = b;
}
return result;
}
调用函数
调用函数需要传递实际参数,下面是调用函数的实际例子:
#import <Foundation/Foundation.h>
@interface SampleClass:NSObject
// 函数声明
- (int)max:(int)num1 andNum2:(int)num2;
@end
@implementation SampleClass
// 返回两个数的最大值
- (int)max:(int)num1 andNum2:(int)num2 {
int result;
if (num1 > num2) {
result = num1;
} else {
result = num2;
}
return result;
}
@end
int main () {
int a = 100;
int b = 200;
int ret;
SampleClass *sampleClass = [[SampleClass alloc]init];
// 调用函数
ret = [sampleClass max:a andNum2:b];
NSLog(@"Max value is : %d\n", ret );
return 0;
}
函数参数
在声明函数的时候,参数称为形式参数,调用函数时需要传递实际参数。
OC中的参数传递实际是值传递,而值传递也有两种方式:
- 实际数据传递,也就是函数复制实际的数据到函数中,如果在函数中对该数据执行更改,则对原来的数据没有影响。
- 引用数值传递,实际是指针传递,也就是复制指针的值到函数中,这样原来的指针和副本指针都指向同一个数据,如果在函数中对该数据有更改,则执行完该函数会原先数据会被改变。
最经典的一个例子就是数据互换了:swap,首先看一下实际数据传递是什么样子的:
- (void)swap:(int)num1 andNum2:(int)num2 {
int temp;
temp = num1;
num1 = num2;
num2 = temp;
return;
}
以上函数不会调换两个变量的数据,你可以动手试下。然后看一下使用指针传递的情况:
- (void)swap:(int *)num1 andNum2:(int *)num2 {
int temp;
temp = *num1;
*num1 = *num2;
*num2 = temp;
return;
}
以上方式可以实现两个变量的数据交换,原因是使用了指针。
OC中指针又称为引用,和C++中的引用是不同的,C++的引用就真是引用,复制的只是变量名(使用变量别名),但是OC中的引用指的是指针。
若无特殊情况,建议使用指针,因为指针只有8个字节,不管多大的数据都只需复制8个字节,但是如果不是指针,复制完整的数据效率将会非常低。
评论前必须登录!
注册