C语言函数

Functions 函数

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

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

Basic Syntax 基本语法

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

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

// main.m
import <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.m
import <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.m
import <Foundation/Foundation.h>

// Declaration
NSString *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 declaration
static int getRandomInteger(int, int);

// Static function implementation
static 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 declaration
static id getRandomItemFromArray(NSArray *anArray);

// Public function implementations
NSString *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 implementation
static id getRandomItemFromArray(NSArray *anArray) {
    int maximum = (int)[anArray count];
    int randomIndex = arc4random_uniform(maximum);
    return anArray[randomIndex];
}

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

// main.m
import <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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值