(2)使用宏可提高程序的通用性和易读性,减少不一致性,减少输入错误和便于修改。例如:数组
(3)预处理是在编译之前的处理,而编译工作的任务之一就是语法检查,预处理不做语法检查。
(4)宏定义末尾不加分号;
(5)宏定义写在函数的花括号外边,作用域为其后的程序,通常在文件的最开头。
(6)可以用#undef命令终止宏定义的作用域
(7)宏定义可以嵌套
(8)字符串" "中永远不包含宏
(9)宏定义不分配内存,变量定义分配内存。
#define S(r) r*r
area=S(a+b);第一步换为area=r*r;,第二步被换为area=a+b*a+b;
(2)宏名和参数的括号间不能有空格
(3)宏替换只作替换,不做计算,不做表达式求解
(4)函数调用在编译后程序运行时进行,并且分配内存。宏替换在编译前进行,不分配内存
(5)宏的哑实结合不存在类型,也没有类型转换。
(6)函数只有一个返回值,利用宏则可以设法得到多个值
下面是预处理后的这条语句:
n=((i)>(((j)>(k)?(j):(k)))?(i):(((j)>(k)?(j):(k))));
=》2宏参数没有类型检查。当一个函数被调用时,编译器会检查每一个参数来确认它们
是否是正确的类型。如果不是,或者将参数转换成正确的类型,或者由编译器产生一个
出错信息。预处理器不会检查宏参数的类型,也不会进行类型转换。
=》3无法用一个指针来指向一个宏。C语言允许指针指向函数。这一概念在特定的编程条
件下非常有用。宏会在预处理过程中被删除,所以不存在类似的“指向宏的指针”。因
此,宏不能用于处理这些情况。
“替代文字”是一个含有编译日期的字符串字面值,日期格式为“mm dd yyyy”
此字符串字面值含有目前源代码文件名称。
一个整数常量,其值是目前源代码的行号(包含__LINE__宏所指的那一行代码),从文件头
此字符串字面值包含编译时间,格式为“hh:mm:ss”(范例:“08:00:59”)。
整数常量1,表示此编译器遵循ISOC标准。
#definePI 3.14159
#defineTWO_PI (2*PI)
当预处理器在后面的程序中遇到TWO_PI时,会将它替换成(2*PI)。接着,预处理器会重新检查
[#undef指令] #undef 标识符
其中标识符是一个宏名。例如,指令
#undef N
会删除宏N当前的定义。(如果N没有被定义成一个宏,#undef指令没有任何作用。)#undef指令的
6=》宏定义中的do-while循环do
那么 /* becomes do { gets(str); } while (0); */
- #define TEST(a, b) a++;b++;
- if (expr)
- TEST(a, b);
- else
- do_else();
- 代码进行预处理后,会变成:
- if (expr)
- a++;b++;
- else
- do_else();
这样if-else的结构就被破坏了if后面有两个语句,这样是无法编译通过的,那为什么非要
do-while而不是简单的用{}括起来呢。 这样也能保证if后面只有一个语句。例如上面的例子,
在调用宏TEST的时候后面加了一个分号, 虽然这个分号可有可无, 但是出于习惯我们一般都会
写上。 那如果是把宏里的代码用{}括起来,加上最后的那个分号。 还是不能通过编译。 所以一
般的多表达式宏定义中都采用do-while(0)的方式。
7.=》总结
好多人不知道平时使用宏定义还是函数 其实我个人挺喜欢用函数的,但是呢各有各的好处。。。。
他们的区别,大家可以看着哪个合适用哪个
1.宏会在编译器在对源代码进行编译的时候进行简单替换,不会进行任何逻辑检测,即简单代码复制而已
2.宏进行定义时不会考虑参数的类型。
3.参数宏的使用会使具有同一作用的代码块在目标文件中存在多个副本,即会增长目标文件的大小。
4.参数宏的运行速度会比函数快,因为不需要参数压栈/出栈操作。
5.参数宏在定义时要多加小心,多加括号。
6.函数只在目标文件中存在一处,比较节省程序空间。
7.函数的调用会牵扯到参数的传递,压栈/出栈操作,速度相对较慢。
8.函数的参数存在传值和传地址(指针)的问题,参数宏不存在。
各有利弊吧看着用,但是宏在有的地方用会有意想不到的结果和便利。。 这些就是我个人的一些见解。。
哈哈终于写完! 有诚意的文章.......(有些是我粘贴复制的,但是都搞清楚了).