宏定义有无参数宏定义和带参数宏定义两种。
无参数的宏定义的一般形式为 # define 标识符 字符序列 其中# define之后的标识符称为宏定义名(简称宏名),要求宏名与字符序列之间用空格符分隔。这种宏定义要求编译预处理程序将源程序中随后所有的定名的出现(注释与字符串常量中的除外)均用字符序列替换之。前面经常使用的定义符号常量是宏定义的最简单应用。如有: # define TRUE 1 # define FALSE 0 则在定义它们的源程序文件中,凡定义之后出现的单词TRUE将用1替代之;出现单词FALSE将用0替代之。 在宏定义的#之前可以有若干个空格、制表符,但不允许有其它字符。宏定义在源程序中单独另起一行,换行符是宏定义的结束标志。如果一个宏定义太长,一行不 够时,可采用续行的方法。续行是在键人回车符之前先键入符号"/"。注意回车要紧接在符号"/"之后,中间不能插入其它符号。 宏定义的有效范围称为宏定义名的辖域,辖域从宏定义的定义结束处开始到其所在的源程序文件末尾。宏定义名的辖域不受分程序结构的影响。可以用预处理命令#undef终止宏定义名的辖域。 在新的宏定义中,可以使用前面已定义的宏名。例如, # define R 2.5 # define PI 3.1415926 # define Circle 2*PI*R # define Area PI* R * R 程序中的Circle被展开为2*3.1415926* 2.5, Area被展开为3.1415926*2.5*2.5。 如有必要,宏名可被重复定义。被重复定义后,宏名原先的意义被新意义所代替。
通常,无参数的宏定义多用于定义常量。程序中统一用宏名表示常量值,便于程序前后统一,不易出错,也便于修改,能提高程序的可读性和可移植性。特别是给数组元素个数一个宏定义,并用宏名定义数组元素个数能部分弥补数组元素个数固定的不足。
则代码 y= MAX( p+q, u+v)将被替换成 y=((p+q) >(u+v)?(p+q):(u+v)。 对于简短的表达式计算函数,或为了提高程序的执行效率、避免函数调用时的分配存储单元、保留现场、参数值传递、释放存储单元等工作。可将函数定义改写成宏定义。所以合理使用宏定义,可以使程序更简洁。
使用一些宏跟踪调试 A N S I标准说明了五个预定义的宏名。它们是: _ L I N E _ (两个下划线),对应%d _ F I L E _ 对应%s _ D A T E _ 对应%s _ T I M E _ 对应%s _ S T D C _ 如果编译不是标准的,则可能仅支持以上宏名中的几个,或根本不支持。记住编译程序 也许还提供其它预定义的宏名。 _ L I N E _及_ F I L E _宏指令在有关# l i n e的部分中已讨论,这里讨论其余的宏名。 _ D AT E _宏指令含有形式为月/日/年的串,表示源文件被翻译到代码时的日期。 源代码翻译到目标代码的时间作为串包含在_ T I M E _中。串形式为时:分:秒。 如果实现是标准的,则宏_ S T D C _含有十进制常量1。如果它含有任何其它数,则实现是 非标准的。 可以定义宏,例如: 当定义了_DEBUG,输出数据信息和所在文件所在行 #ifdef _DEBUG #define DEBUGMSG(msg,date) printf(msg);printf(“%d%d%s”,date,_LINE_,_FILE_) #else #define DEBUGMSG(msg,date) #endif 20,宏定义防止使用是错误 用小括号包含。 例如:#define ADD(a,b) (a+b) 用do{}while(0)语句包含多语句防止错误 例如:#difne DO(a,b) a+b;/ a++; 应用时:if(….) DO(a,b); //产生错误 else
解决方法: #difne DO(a,b) do{a+b;/ a++;}while(0)
#define STR(s) #s
int main()
二、当宏参数是另一个宏的时候
1, 非''#''和''##''的情况
printf("%d*%d=%d/n", TOW, TOW, MUL(TOW,TOW));
2, 当有''#''或''##''的时候
printf("int max: %s/n", STR(INT_MAX)); // INT_MAX #include<climits>
printf("%s/n", CONS(A, A)); // compile error
INT_MAX和A都不会再被展开, 然而解决这个问题的方法很简单. 加多一层中间转换宏.
#define A (2)
printf("int max: %s/n", STR(INT_MAX)); // INT_MAX,int型的最大值,为一个变量 #include<climits>
printf("%d/n", CONS(A, A));
三、''#''和''##''的一些应用特例
2、填充结构
enum IDD{OPEN, CLOSE};
MSG _msg[] = {FILL(OPEN), FILL(CLOSE)};
3、记录文件名
4、得到一个数值类型所对应的字符串缓冲大小 char buf[11] 本文转载自http://hi.baidu.com/ufo008ahw/blog/item/5e943d4f5f49513caec3abd1.html) |
|
来自: qingxiangwang > 《宏》