在C&C++中,宏的使用,提高了不少程序编写的效率,同样也提高了程序运行的效率,但这是由空间换去时间的一种方式。宏只进行非字符串的文本替换,如:
#define MAXLINE 100
int main(){
char *file[MAXLINE];
printf("MAXLINE/n");
//...... }
此时,char *file[MAXLINE]在编译时,被预处理器将MAXLINE替换成100,即char *file[100];而字符串"MAXLINE"将被预处理器忽略。
宏也可以定义为类似函数的宏函数,但宏函数名与宏变量左括号必需紧接着的,不能出现空格;
如:#define MAX(x,y) x>y?x:y
但如果仅像宏MAX(x,y)那样定义,在一般x,y都是数值的情况下,不会出来问题,但如果x,y是表达式的话,就有可能会出现完全不同的效果,故因此一般在定义带“变量”的宏函数,都给函数加上“()”,所以MAX(x,y)应定义为#define MAX(x,y) ((x)>(y)?(x):(y))。
即便是有上述那种定义方式,宏仍然可能展开后运行得不到预期的效果;如 i=10; MAX(++i,0); 输出为11是预期的结果,然后实际输出为12;展开后可以看到i做了两次自增运算;这并是宏对表达式处理无法避免的问题。
宏在定义多行函数体时,用"/"进行函数体分行,注意的是"/"后不能出现任何符号,包括空格符;
#define PRT cout<<"this is a multiline test" /
<<"these lines can be connected with" /
<<"//"<<endl;
宏的定义还有两个比较实用的用法,一个是字符串连接,一个是字符串粘贴;
字符串连接是出现在两个字符串之间无间隔符的情况下,且#插入定义的宏变量,即可将宏变量转为字符串进行连接。如:#define PRT(s) cout<<#s<<endl; PRT(getchar()) 展开后为 cout<<"getchar()"<<endl;
字符串粘贴语法为"宏变量名## " ,如 #define DIM(a) int ##a_integer; char ##a_char; DIM(first) 展开后为:int first_integer; char first_char; 字符串粘贴只适合于宏变量名的字符替换,若要将函数名置入变量,在编译过程中将无法通过,如,DIM(f())展开后 int f()_integer;char f()_char; 这都是非法的变量名定义。