C语言函数

来源:互联网 发布:始作俑者其无后乎 甄嬛 编辑:程序博客网 时间:2024/06/15 00:34

Functions 函数

和变量、控制流、条件一样、函数也是现代编程语言的基本组成部分。他可以使我们在应用中重复利用一块代码,对于代码的组织和维护是很有必要的。您将在IOS和OS X的框架中发现大量的例子。

像其他的基础元素一样,Object-C的函数也是建立在C语言函数之上的。这章我们将介绍C语言最重要的方面,包括基本语法、声明和实现、变量生命周期以及函数库的注意事项。

Basic Syntax 基本语法

C语言的函数有四部分组成:返回值、函数名、参数以及相关的代码块。定义之后,您可以通过传递必要的参数,调用函数,执行相关的代码。

比如,下面的例子,定义一个getRandomInteger函数,接受两个int类型的参数,返回一个int类型的返回值。在函数内部,我们通过minimum 和maximum 参数获取传递给函数的值,通过reture关键字返回计算的值。在main函数中,我们可以通过传递10和-10作为参数,调用函数。

// main.mimport <Foundation/Foundation.h>int getRandomInteger(int minimum, int maximum) {    return arc4random_uniform((maximum - minimum) + 1) + minimum;}int main(int argc, const char * argv[]) {    @autoreleasepool {        int randomNumber = getRandomInteger(-10, 10);        NSLog(@"Selected a random number between -10 and 10: %d",              randomNumber);    }    return 0;}

内置的函数arc4random_uniform,可以返回从0到您传递参数的一个随机数。

函数可以使用指针引用作为函数的返回值和参数,这就意味着您可以同样的方式使用Object-C的对象。比如,在main中添加如下代码。

// main.mimport <Foundation/Foundation.h>NSString *getRandomMake(NSArray *makes) {    int maximum = (int)[makes count];    int randomIndex = arc4random_uniform(maximum);    return makes[randomIndex];}int main(int argc, const char * argv[]) {    @autoreleasepool {        NSArray *makes = @[@"Honda", @"Ford", @"Nissan", @"Porsche"];        NSLog(@"Selected a %@", getRandomMake(makes));    }    return 0;}

getRandomMake 接受NSArray类型的对象作为参数,返回NSString类型的对象。注意,它同样使用*语法,声明指针变量。

Declarations vs. Implementations 声明 vs 实现

在使用函数之前,您必须定义函数。如果您定义getRandomMake函数在main函数之后,当您调用这个函数时,编译器是找不到这个函数的。这样强加了一个限制,不利于大型项目有的组织。为了解决这个问题,C语言将函数的声明和实现分开了。

Function declarations vs. implementations

函数的声明是告诉编译器,函数的输入和输出是什么样的。通过提供返回数据类型和参数,编译器确认您是否正确使用函数,但是不知道函数具体的实现。相应的函数实现实在声明的基础上添加了一块代码。

下面的代码声明了函数getRandomMake ,所以您可以在main中调用,而且函数还没有被实现。注意,函数申明中只需要参数的类型,参数的名字是可以省略的。

// main.mimport <Foundation/Foundation.h>// DeclarationNSString *getRandomMake(NSArray *);int main(int argc, const char * argv[]) {    @autoreleasepool {        NSArray *makes = @[@"Honda", @"Ford", @"Nissan", @"Porsche"];        NSLog(@"Selected a %@", getRandomMake(makes));    }    return 0;}

// Implementation
NSString *getRandomMake(NSArray *makes) {
int maximum = (int)[makes count];
int randomIndex = arc4random_uniform(maximum);
return makes[randomIndex];
}

正如您将要看到的,分离函数的声明和实现,对于组织打的项目是很有用的。

The Static Keyword Static 关键字

static 关键字可以改变函数和变量的可见性。不幸的是,它的作用和他所使用的位置有关。本小节常用的两个static用法。

Static Functions static 函数

通常函数时全局可见的。也就是说,一旦您定义了一个函数,您在其他任何地方都可以调用这个函数。static关键字可以限制函数只在当前文件中可见,这样对于创建一个私有的函数和防止命名冲突很有用。

Globally-scoped functions vs. statically-scoped functions

下面是怎样创建一个static函数的例子,如果您在另外一个文件声明和实现函数,您在main函数中是不能调用函数的。注意static在函数的声明和实现中都使用了。

// Static function declarationstatic int getRandomInteger(int, int);// Static function implementationstatic int getRandomInteger(int minimum, int maximum) {    return arc4random_uniform((maximum - minimum) + 1) + minimum;}

Static Local Variables 静态本地变量

声明在函数中的变量,每次执行的时候都会被初始化。这是一个很直观的默认行为,也就是说函数会忘记,您调用它多少次。但是,如果您使用static声明本地变量,函数可以记住不同调用的值。

Independent automatic variables vs. shared static variables

比如,下面的变量currentCount ,从来都不会被重新初始化。我们不在main中定义技术变量,我们可以使用countByTwo计数。

// main.m#import <Foundation/Foundation.h>int countByTwo() {    static int currentCount = 0;    currentCount += 2;    return currentCount;}int main(int argc, const char * argv[]) {    @autoreleasepool {        NSLog(@"%d", countByTwo());    // 2        NSLog(@"%d", countByTwo());    // 4        NSLog(@"%d", countByTwo());    // 6    }    return 0;}

不想上节介绍的static函数,static不影响变量的可见性。所以本地变量只能在函数中访问。

Function Libraries 函数库

Objec-C不支持命名空间,为了防止命名的冲突,我们在函数名之前加上前缀,比如NSMakeRange和CGImageCreate。

当您创建自己的函数时,函数的声明和实现,在不同的文件中。这样使引入头文件的文件不必担心函数的实现。比如CarUtilities 的头文件如下所示:

// CarUtilities.h#import <Foundation/Foundation.h>NSString *CUGetRandomMake(NSArray *makes);NSString *CUGetRandomModel(NSArray *models);NSString *CUGetRandomMakeAndModel(NSDictionary *makesAndModels);

相应的实现文件定义函数的具体实现。因为文件不支持引入函数实现,您可以使用static关键字,创建一个私有的函数。

// CarUtilities.m#import "CarUtilities.h"// Private function declarationstatic id getRandomItemFromArray(NSArray *anArray);// Public function implementationsNSString *CUGetRandomMake(NSArray *makes) {    return getRandomItemFromArray(makes);}NSString *CUGetRandomModel(NSArray *models) {    return getRandomItemFromArray(models);}NSString *CUGetRandomMakeAndModel(NSDictionary *makesAndModels) {    NSArray *makes = [makesAndModels allKeys];    NSString *randomMake = CUGetRandomMake(makes);    NSArray *models = makesAndModels[randomMake];    NSString *randomModel = CUGetRandomModel(models);    return [randomMake stringByAppendingFormat:@" %@", randomModel];}// Private function implementationstatic id getRandomItemFromArray(NSArray *anArray) {    int maximum = (int)[anArray count];    int randomIndex = arc4random_uniform(maximum);    return anArray[randomIndex];}

现在,您可以引入头文件,调用函数,如果定义在同一个文件中。如果您试图在main中调用getRandomItemFromArray ,将会导致一个编译错误。

// main.mimport <Foundation/Foundation.h>import "CarUtilities.h"int main(int argc, const char * argv[]) {    @autoreleasepool {        NSDictionary *makesAndModels = @{            @"Ford": @[@"Explorer", @"F-150"],            @"Honda": @[@"Accord", @"Civic", @"Pilot"],            @"Nissan": @[@"370Z", @"Altima", @"Versa"],            @"Porsche": @[@"911 Turbo", @"Boxster", @"Cayman S"]        };        NSString *randomCar = CUGetRandomMakeAndModel(makesAndModels);        NSLog(@"Selected a %@", randomCar);    }    return 0;}

Summary 总结

本章用函数介绍,结束了C语言基础讲解。我们学习了声明函数和实现函数,改变他们的可见性,使记住本地变量,和组织大的函数库。

Cocoa 和Cocoa Touch 中大部分功能都分装的类中。现在我们已经做好了,学习Object-C面向对象特性了,下章我们将学习类的定义、对象初始化、属性的设置已经方法的调用。

1 0