C语言_宏定义与使用分析

定义宏常量

  • #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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值