二、宏
  宏定义了一个代表特定内容的标识符。预处理过程会把源代码中出现的宏标识符替换成宏定义时的值。宏常见的用法是定义代表某个值的全局符号。宏的第二种用法是定义带参数的宏,这样的宏可以象函数一样被调用,但它是在调用语句处展开宏,并用调用时的实际参数来代替定义中的形式参数。
  1.#define指令
  #define预处理指令是用来定义宏的。该指令简单的格式是:首先神明一个标识符,然后给出这个标识符代表的代码。在后面的源代码中,用这些代码来替代该标识符。这种宏把程序中要用到的一些全局值提取出来,赋给一些记忆标识符。
  #define MAX_NUM 10
  int array[MAX_NUM];
  for(i=0;i<MAX_NUM;i++)  /*……*/
  在这个例子中,对于阅读该程序的人来说,符号MAX_NUM有特定的含义,它代表的值给出了数组所能容纳的大元素数目。程序中可以多次使用这个值。作为一种约定,习惯上总是全部用大写字母来定义宏,这样易于把程序红的宏标识符和一般变量标识符区别开来。如果想要改变数组的大小,只需要更改宏定义并重新编译程序即可。
  宏表示的值可以是一个常量表达式,其中允许包括前面已经定义的宏标识符。例如:
  #define ONE 1
  #define TWO 2
  #define THREE (ONE+TWO)
  注意上面的宏定义使用了括号。尽管它们并不是必须的。但出于谨慎考虑,还是应该加上括号的。例如:
  six=THREE*TWO;
  预处理过程把上面的一行代码转换成:
  six=(ONE+TWO)*TWO;
  如果没有那个括号,转换成six=ONE+TWO*TWO;了。
  宏还可以代表一个字符串常量,例如:
  #define VERSION "Version 1.0 Copyright(c) 2003"
  2.带参数的#define指令
  带参数的宏和函数调用看起来有些相似。看一个例子:
  #define Cube(x) (x)*(x)*(x)
  可以时任何数字表达式甚至函数调用来代替参数x。这里再次提醒大家注意括号的使用。宏展开后完全包含在一对括号中,而且参数也包含在括号中,这样保证了宏和参数的完整性。看一个用法:
  int num=8+2;
  volume=Cube(num);
  展开后为(8+2)*(8+2)*(8+2);
  如果没有那些括号变为8+2*8+2*8+2了。
  下面的用法是不安全的:
  volume=Cube(num++);
  如果Cube是一个函数,上面的写法是可以理解的。但是,因为Cube是一个宏,所以会产生副作用。这里的擦书不是简单的表达式,它们将产生意想不到的结果。它们展开后是这样的:
  volume=(num++)*(num++)*(num++);
  很显然,结果是10*11*12,而不是10*10*10;
  那么怎样安全的使用Cube宏呢?必须把可能产生副作用的操作移到宏调用的外面进行:
  int num=8+2;
  volume=Cube(num);
  num++;
  3.#运算符
  出现在宏定义中的#运算符把跟在其后的参数转换成一个字符串。有时把这种用法的#称为字符串化运算符。例如:
  #define PASTE(n) "adhfkj"#n
  main()
  {
  printf("%s ",PASTE(15));
  }
  宏定义中的#运算符告诉预处理程序,把源代码中任何传递给该宏的参数转换成一个字符串。所以输出应该是adhfkj15。