宏定义与使用分析
1. 定义宏常量
(1)#define 定义宏常量可以出现在代码的任何地方
(2)#define从本行开始,之后的代码都可以使用这个宏常量
#define ERROR -1 //正确 #define PI 3.1415926 //正确 #define PATH_2 "D:\Delphi\C\Topic3.ppt" //正确 #define PATH_1 D:\Delphi\C\Topic3.ppt //正确,因为预编译器只是简单的替换 #define PATH_3 D:\Delphi\C\ Topic3.ppt //正确,这里的\是接续符
2. 定义宏表达式
(1)#define表达式给有函数调用的假象,却不是函数
(2)#define表达式可以比函数更加强大
(3)#define表达式比函数更容易出错
#include <stdio.h> #define SUM(a, b) (a)+(b) #define MIN(a, b) ((a)<(b)? (a):(b)) #define DIM(a) (sizeof(a)/sizeof(*a)) int sum(int a, int b) { return a+b; } int min(int a, int b) { return ((a)<(b)? (a):(b)); } int dim(int array[]) { return sizeof(array) / sizeof(*array); } int main() { int i = 1; int j = 5; int a[] = {1, 2, 3} printf("%d\n", SUM(1, 2) * SUM(1, 2)); //相当于(1)+(2) * (1)+(2),输出为5 printf("%d\n", sum(1, 2) * sum(1, 2)); printf("%d\n", MIN(i++, j)); //相当于((i++)<(j)? (i++): (j)),输出是2 printf("%d\n", min(i++, j)); //输出是1 printf("%d\n", DIM(a); //输出3,数组元素个数;而使用函数比较难实现 printf("%d\n", dim(a); //输出为1,因为函数的数组参数会退化为一个指针,那么sizeof(array)就是一个指针所占用空间的大小 }
【编程实验—宏代码块的定义(宏强于函数的优势)】
#include <stdio.h> #include <malloc.h> #define MALLOC(type, x) (type*)malloc(sizeof(type)*x) #define FOREVER() while(1) #define BEGIN { #define END } #define FOREACH(i, m) for(i=0; i<m; i++) int main() { int array[] = {1, 2, 3, 4, 5}; int x = 0; int*p = MALLOC(int, 5); FOREACH(x, 5) BEGIN p[x] = array[x]; END FOREACH(x, 5) BEGIN printf("%d\n", p[x]); END FOREVER(); free(p); printf("Last printf...\n"); return 0; }
3. 宏表达式与函数的对比
(1)宏表达式在预编译期被处理,编译器不知道宏表达式的存在
(2)宏表达式用“实参”完全替代形参,不进行任何运算
(3)宏表达式没有任何的“调用”开销
(4)宏表达式中不能出现递归定义,如:
#define FAC(n) ((n>0) ? (FAC(n-1)+1) : 0) int j = FAC(100);
4. 你见过#undef吗?
- 宏定义的常量或表达式是否有作用域的限制?
#include <stdio.h> int f1(int a, int b) { #define _MIN_(a,b) ((a)<(b) ? a : b) return _MIN_(a, b);
#undef _MIN_(a,b) //下面就不可以再使用该宏,用#undef来实现作用域的限制 } int f2(int a, int b, int c) { return _MIN_(_MIN_(a,b), c); } int main() { printf("%d\n", f1(2, 1)); printf("%d\n", f2(5, 3, 2)); return 0; }
5. 强大的内置宏
【编程实验—定义日志宏】
#include<stdio.h> #include<time.h> #define LOG(s) do{ \ time_t t; \ struct tm* ti; \ time(&t); \ ti = localtime(&t); \ printf("%s[%s:%d] %s\n", asctime(ti), __FILE__, __LINE__, s); \ }while(0) void f() { LOG("Enter f()...."); LOG("Exit f()...."); } int main() { LOG("Enter main()...."); f(); LOG("Exit main()..."); }