定义宏常量
- #define定义宏常量可以出现在代码的任何地方
- #define从本行开始,之后的代码都可以使用这个宏常量
就是简单的文本替换,错误格式的文本也直接替换
定义宏表达式
- #define表达式给有函数调用的假象,却不是函数
- #define表达式可以比函数更强大
- #define表达式比函数更容易出错
#define SUM(a,b) (a)+(b)
#define MIN(a,b) ((a)<(b)?(a):(b))
#define DIM(a,b) (sizeof(a)/sizeof(*a)) //这个比较牛逼,用函数不能实现,函数传数组,只能传首位的指针
这三个宏可以用函数替换
容易出错的点
#include <stdio.h>
#define SUM(a,b) (a)+(b)
#define MIN(a,b) ((a)<(b)?(a):(b))
#define DIM(a,b) (sizeof(a)/sizeof(*a))
int dim(int array[])
{ //函数不能实现,函数传数组,只能传首位的指针
return sizeof(array)/array(*array); //1
}
int main()
{
int i = 1;
int j = 5;
printf("%d\n",SUM(1,2)*SUM(1,2));
//(1)+(2)*(1)+(2) 就跟本意不同了
printf("%d\n",MIN(i++,j));
//(i++)<(j)?(i++):(j) 这个等同于if else 第一个i++会加上1
return 0;
}
宏强于函数的优势在哪
很尬,不知道有啥用
#define BEGIN {
#define END }
#define FOREVER while(1)
差不多就是这样,然后让宏写代码😓
宏表达式与函数的对比
-
宏表达式在预编译期被处理,编译器不知道宏表达式的存在
-
宏表达式用"实参"完全替代形参,不进行任何运算
-
宏表达式没有任何的"调用"开销
-
宏表达式中不能出现递归定义
-
#define FAC(n) ( (n>0) ? (FAC(N-1)-1) : 0 ) int j = FAC(100); //预编译之后 int j = ((100>0) ? (FAC(100-1)-1) : 0)
-
宏定义的作用域 与 #undef
例:
#include <stdio.h>
int f1(int a,int b)
{ //宏定义
#define _MIN_(a,b) ((a)<(b)?a:b)
return _MIN_(a,b);
}
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;
}
#undef
#undef
指令⽤来取消已经使⽤ #define 定义的宏
#define LIMIT 400
#undef LIMIT
上面例子中#undef
指令用于取消 已经定义的宏LIMIT
,后面可以用LIMIT
重新定义新的宏。
对于刚才讲作用域的示例代码
#include <stdio.h>
int f1(int a,int b)
{
#define _MIN_(a,b) ((a)<(b)?a:b) //定义宏
return _MIN_(a,b);
#undef _MIN_ //取消宏定义
}
int f2(int a,int b,int c)
{
return _MIN_(_MIN_(a,b),c); //报错,_MIN_未定义
}
强大的 内置宏
__DATE__
:编译⽇期,格式为“Mmm dd yyyy”的字符串(⽐如 Nov 23 2021)。__TIME__
:编译时间,格式为“hh:mm:ss”。__FILE__
:当前⽂件名。__LINE__
:当前⾏号。__func__
:当前正在执⾏的函数名。该预定义宏必须在函数作⽤域使⽤。__STDC__
:如果被设为1,表示当前编译器遵循 C 标准。
定义日志宏
#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)
//浅浅调用一下
int main()
{
LOG("OK!");
//输出
//Tue May 17 20:28:30 2022
//[d:\Learning\Environment\code_c\C_single\exercise\text.c:15] OK!
return 0;
}
思考
-
#define f (×) ((×)-1)
的宏定义代表什么意思?#define f (×) ((×)-1) //编译器认为这是定义了一个宏:f,其代表是(x) ((x)-1) int main(){ f //经过预编译后 (×) ((×)-1) }
-
宏定义对空格敏感吗?宏"调用"对空格敏感吗?
回去看c primer