条件编译通常用于创建可以 在不同计算机系统上编译运行的程序,它还经常用来开关程序中的各种语句。
1.#ifdef #endif #else 和#ifndef语句
程序有时必须依靠系统相关的参数,这些参数在不同的设备(例如:ipad和iphone)或特定版本的操作系统的值不同。如果有大型程序,它对计算机系统的硬件或软件有很多这样的依赖(应该尽量减少这种依赖性),最终你可能会有许多这样的定义,在程序移植到其他的其他计算机系统时,他们的值不得不更改。
例如:
#ifdef IPAD
# define KImageFile @"barnHD.png"
#else
# define KImageFile @"barn.png"
#elseif
这里第二行代码允许在标志预处理程序语句的#厚有若干个空格。如果程序编译时,#ifdef行中的所指定的符号已经通过#define语句或命令行定义了,那么编译器将处理从此初开始开始到#else #endif #elif的程序段,否则忽略这个程序段。
要为预处理程序定义符号IPAD,可以使用如下语句:#define IPAD 1或者仅仅#define IPAD。还可以使用编译器命令的特殊选项在程序编译时为编译器定义名称。
#ifndef 语句与#ifdef在一条线上,这个语句的使用方式类似,只是如果指定的符号没有定义,它将导致程序处理后续行为。
在调试程序的时候,条件编译很有用,你可能在程序中嵌入了很多NSLog语句,用于显示中间的结果,并跟踪执行流程。可以在程序中定义一个DEBUG,就可以使用如下语句:
#ifdef DEBUG
NSLog(@"...");
#endif
这种语句可以出现在程序中任何地方,不一定是文件的开始。
2.#if和#elif预处理语句
if语句可以用来检测常量表达式是否为非零。如果表达式的结果为非零,就会处理到#else #elif 或#endif为止的所有后续行;否则忽略它们。
例如:在Foundation头文件NSString.h中有以下几行:
#if MAC_OS_VERSION_MIN_REQUIRED <MAC_OS_VERSION_10_5
#define NSMaximumStringLength (INT-MAX-1)
#endif
特殊运算符defined (name)也能够用在#if语句中,而且
#if defined (DEBUG)
...
#endif
和
#ifdef DEBUG
....
#endif
的作用相同。
还有另一种方法,如下:
#if defined (DEBUG) && DEBUG
...
#endif
此语句只有在定义了DEBUG而且具有非零值时才被处理。
很多人都知道,#if 0 ... #endfif的作用跟/*...*/的作用是一样的,就是注释,可是注释为什么不用注释符号/*就行了么?大家都说是为了解决嵌套注释。如:
/*--------------------------------------------------------------------*/
#include“stdio.h”
int main()
{
int a=11;
/*这是一个外层注释
/*
int *b=&a; //这是一个内层代码注释
*b = 10;
*/
a++;
*/
}
/*----------------------------------------------------------------------*/
上面的程序编译后发现缺少了一个注释符号,因为注释符头 " / * "是根据最近结束符 " */ "来判断注释的区域的,但是一但内嵌了就会发现错误。所以人们就使用了#if 0,如下:
/*--------------------------------------------------------------------*/
#include“stdio.h”
int main()
{
int a=11;
/*这是一个外层注释
#if 0
int *b=&a; //这是一个内层代码注释
*b = 10;
#endif
a++;
*/
}
/*----------------------------------------------------------------------*/
但是,#if就只有这个作用吗?有些书籍呼吁人们尽量少用它,那不是没有什么意义了?
其实不是的,在有些地方很常见到它,而且少不了它。当你见识过系统级的源代码就焕然大悟了。对,就是用于系统裁剪。
系统裁剪是针对系统的用途,对系统的源代码进行一下优化,减少不必要的功能。
#if是一个最经典的例子。如:
/*--------------------------------------------------------------------*/
#include“stdio.h”
#define TEST_2 1
int main()
{
int a=11;
/*这是一个外层注释
#if TEST_2
int *b=&a;
*b = 10;
#endif
a++;
*/
}
/*----------------------------------------------------------------------*/
如上面的例子,对于某些功能不需要,我们只需对于的功能TEST_2的宏定义改成0,然后重新编译就行了。当然一般宏定义是放在一个特定的文件(这里为了简单就写在一起),这样外面的人只需要更改那个文件所对应的值就行对系统进行裁剪而不需要关心具体代码,就行实现裁剪。
/*--------------------------------------------------------------------*/
#include“stdio.h”
int main()
{
int a=11;
/*这是一个外层注释
/*
int *b=&a; //这是一个内层代码注释
*b = 10;
*/
a++;
*/
}
/*----------------------------------------------------------------------*/
上面的程序编译后发现缺少了一个注释符号,因为注释符头 " / * "是根据最近结束符 " */ "来判断注释的区域的,但是一但内嵌了就会发现错误。所以人们就使用了#if 0,如下:
/*--------------------------------------------------------------------*/
#include“stdio.h”
int main()
{
int a=11;
/*这是一个外层注释
#if 0
int *b=&a; //这是一个内层代码注释
*b = 10;
#endif
a++;
*/
}
/*----------------------------------------------------------------------*/
但是,#if就只有这个作用吗?有些书籍呼吁人们尽量少用它,那不是没有什么意义了?
其实不是的,在有些地方很常见到它,而且少不了它。当你见识过系统级的源代码就焕然大悟了。对,就是用于系统裁剪。
系统裁剪是针对系统的用途,对系统的源代码进行一下优化,减少不必要的功能。
#if是一个最经典的例子。如:
/*--------------------------------------------------------------------*/
#include“stdio.h”
#define TEST_2 1
int main()
{
int a=11;
/*这是一个外层注释
#if TEST_2
int *b=&a;
*b = 10;
#endif
a++;
*/
}
/*----------------------------------------------------------------------*/
如上面的例子,对于某些功能不需要,我们只需对于的功能TEST_2的宏定义改成0,然后重新编译就行了。当然一般宏定义是放在一个特定的文件(这里为了简单就写在一起),这样外面的人只需要更改那个文件所对应的值就行对系统进行裁剪而不需要关心具体代码,就行实现裁剪。
3.#undef语句
在一些情况下,可能需要使用一些已经定义的名称称为未定义的通常使用#undef语句就可以这么么做,格式:
#undef name