如果您无法下载资料,请参考说明:
1、部分资料下载需要金币,请确保您的账户上有足够的金币
2、已购买过的文档,再次下载不重复扣费
3、资料包下载后请先用软件解压,在使用对应软件打开
使用预处理程序的提示和技巧(1)任何读过C源代码的人都看到过预处理指令。例如,你会在大多数源文件的开头看到include指令(#include)。预处理程序是在实际编译器看到源代码之前将其重新编写的一种系统。显然,它是一个功能非常强大的工具。缺点是可能会不小心砸到自己的脚。有关预处理程序的文章有两部分,本文是其中的第一部分。本文中,我们引人预处理器,并包含了基本的内容,包括对象和函数类宏、include指令、条件编译、以及以两条特殊指令#error和#pragma。下一篇文章中将涉及到常见的预处理程序错误和标准C文献中不常见的高级预处理程序主题。#include指令#include是最直接的预处理程序指令。当预处理程序发现了这条指令,它就会打开指定的文件并插入内容,而文件内容是写在指令所处的位置处。可以采用两种形式,如:#include<systemfile.h>#include"myfile.h"第一个用于包含标准头文件,如stdio.h.。第二个用于用户自定义头文件。♦宏预处理程序最有用的特点之一就是允许用户自己定义宏,也就是映射到一段代码的用户标识符。预处理程序无论何时在应用程序源代码中发现了宏,它就会用定义来代替宏。基本上有两类宏,对象宏和函数宏。区别是函数宏有参数。按照贯例,宏的名字只用大写来书写。唯一的特例是因为效率的原因用一个宏来代替一个函数。指令#define是用来定义一个宏的。下例中,我们把NUMBER_OF_PLAYERS定义为常数2。这是一个对象宏。#defineNUMBER_OF_PLAYERS2intcurrent_score[NUMBER_OF_PLAYERS];这里,函数宏PRINT_PLAYER映射到一段更复杂的代码。#definePRINT_PLAYER(no)printf("Player%disnamed%s",no,names[no])从技术上来说,宏的定义必须出现在同一行源代码中。幸运的是,标准C允许你用反斜杠来作为一行的结尾然后在下一行中继续。如:#defineA_MACRO_THAT_DOES_SOMETHING_TEN_TIMES\for(i=0;i<10;++i)\{\do_something();\}除了用户可定义的宏以外,C标准中还有很多预先定义好的存于库中的宏可以供使用。如,__FILE__包含现有源文件名字,以字符串的形式。如果你想使一个宏不被定义,可以用#undef指令。♦对象宏对象宏可以用来使用一些源代码来替代源码中的某个用户标识符。典型地,宏可以用来声明某一位置处配置的常数。而且,常数可以令代码更具可读性,即使其值并不需要改变。例如:#defineSQUARE_ROOT_OF_TWO1.4142135623730950488016887doubleconvert_side_to_diagonal(doublex){returnx*SQUARE_ROOT_OF_TWO;}doubleconvert_diagonal_to_side(doublex){returnx/SQUARE_ROOT_OF_TWO;}预处理程序可以用来解决非常奇怪的事情,因为预处理程序所做的就是以抽象的源代码来代替用户标识符。如,以下是合法的代码(尽管假如你要写出类似的代码,还需要向老板解释):#defineBLA_BLA);inttest(intx){printf("%d",xBLA_BLA}♦函数宏函数宏是有参数的宏。当你使用它们时,就像是函数调用。函数宏如下列代码:#defineSEND(x)output_array[output_index++]=x当预处理程序发现应用程序源代码中有函数宏,它就会用定义来代替它。宏参数会在参数变量位置处插入最终的源代码。因此,如果你写了下列代码:SEND(10)编译器会看到:output_array[output_index++]=10在第二部分中我们还会提到函数宏,并讨论其中可能的陷阱。♦条件编译预处理程序最强大的功能之一是条件编译—也就是说某些条件下,有些代码可能被排除在实际编译之外。这意味着如果你的源代码中包含如ARM处理器的特殊代码,使用条件编译就可以在编译其他所有处理器时忽视这部分代码。预处理指令#ifdef,#ifndef,#if,#elif,和#else是用来控制源代码的。假如已经定义了预处理符号,则#ifdef指令将会包含一部分源代码,#ifndef反之。如:#ifdefARM_BUILD__ARM_do_something();#e