跳转至

宏定义

头文件加保护

预处理指令

头文件加保护,防止多重包含,避免重复编译头文件。

一般是这样的形式

#ifndef XXXXX_H    // 如果没有定义 XXXXX_H
#define XXXXX_H   // 先定义 XXXXX_H,那么下一次编译到这个头文件的时候上一句条件不成立,下面的内容就不会再编译了。

// 头文件中的代码

#endif

在 C++ 中,可以用#pragma once来代替,使用了 #pragma once 之后就可以不去判断有没有编译过这个头文件,由编译器自己判断。

只要写头文件 都要写头文件的保护。

宏、全局变量、常量的选择

全局共用一些数据时,可以用宏、变量、常量

  • 宏:只是在预处理器里进行文本替换,没有类型,不做任何类型检查,编译器可以对相同的字符串进行优化。只保存一份到 .rodata 段。甚至有相同后缀的字符串也可以优化,你可以用GCC 编译测试,"Hello world" 与 "world" 两个字符串,只存储前面一个,取的时候只需要给前面和中间的地址。如果是整形、浮点型会有多份拷贝,但这些数写在指令中,占的只是代码段而已,大量用宏会导致二进制文件变大。
  • 全局变量:共享一块内存空间,就算项目中N处用到,也不会分配N块内存空间,可以被修改,在编译阶段会执行类型检查。
  • 常量:共享一块内存空间,就算项目中N处用到,也不会分配N块内存空间,可以根据const修饰的位置设定能否修改,在编译阶段会执行类型检查。

尽量使用const,看苹果api使用常量多点,如下:

UIKIT_EXTERN NSString *const UIKeyboardFrameBeginUserInfoKey        API_AVAILABLE(ios(3.2)) API_UNAVAILABLE(tvos); // NSValue of CGRect

常量

1、全局常量

不管定义在任何文件夹,外部都能访问

在ViewController.m源文件中定义一个 haha 字符串全局常量:

NSString *const haha = @"hahahaha";

在AppDelegate中访问:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    extern NSString *haha;
    NSLog(@"我是haha:%@",haha);//我是haha:hahahaha
    return YES;
}

一般项目中,定义全局常量,会写在独立文件里

HHConst.h文件

UIKIT_EXTERN NSString *const NETWORK_ERROR;

HHConst.m文件

NSString *const NETWORK_ERROR = @"网络出错,请稍后再试";

extern

extern会声明一个工程内全局共享变量,但不给予实现,也就是不会为其申请内存,等到定义时才会申请内存空间。

// .h
extern int var;
// .m
int var = 10;

2、局部常量

static修饰后,不能提供外界访问,只能本文件内访问。

例如:

在ViewController定义一个 haha 字符串局部常量:

#import "ViewController.h"
static const NSString *haha = @"hahahaha";

const修饰位置不同,代表什么?

const NSString *HSCoder = @"汉斯哈哈哈";
"*HSCoder"不能被修改 "HSCoder"能被修改

NSString const *HSCoder = @"汉斯哈哈哈";
"*HSCoder"不能被修改 "HSCoder"能被修改

NSString * const HSCoder = @"汉斯哈哈哈";
"HSCoder"不能被修改"*HSCoder"能被修改

结论:const右边的总不能被修改

定义一个常量,其它文件可以访问,但是不能修改

NSString * const HSCoder = @"汉斯哈哈哈";