【C】「#define」

目录

无参宏定义

有参宏定义

带副作用的参数

「#」

「##」

「#undef」

宏的优缺点

offsetof 模拟实现


#define:用于定义一个宏,「#」表示这是一条预处理指令;「define」为宏定义命令

宏:一种批量处理的称谓,程序预编译期间将所有使用的宏替换为对应「宏体」(常量、常量字符串、关键字、语句 ......)

宏定义的宏名称作「标识符」,具有常属性,不可修改

宏定义分为「无参宏定义」和「有参宏定义」

参宏定义

#define 宏名 宏体

定义常量

#define MAX 1000  //将MAX定义为常量1000

定义关键字

#define reg register //将reg定义为register(寄存器)

定义语句

#define do_forever for(;;)  //将do_forever定义为死循环

若定义语句过长需要分行,续在末尾加上续航符「\」

#define DEBUG_PRINT printf("路径:%s  行数:%d  日期:%s  时间%s",\
							__FILE__,__LINE__ ,__DATE__,__TIME__)
//将DEBUG_PRINT定义为打印相应内容

有参宏定义

将对应内容替换为参数,类似函数

#define 宏名(参数) 宏体
#define SQUARE(x) x*x

int main()
{
	int a = SQUARE(1);
    //替换后:int a = 1 * 1
	printf("%d", 1);//输出1
	return 0;
}

注意事项:尽可能地将宏体、宏体内符号加上括号

#define SQUARE(x) ((x)*(x))

宏进行的是替换操作,如果不加上必要的括号,会导致结果不同于预期

不加括号:
#define SQUARE(x) x*x

int main()
{
	int a = 2 + 2;
	int b = 10 * SQUARE(a);
	//替换后:int b = 10 * 2 + 2 * 2 + 2;
	printf("%d", b);//输出26
	return 0;
}


加括号:
#define SQUARE(x) ((x)*(x))

int main()
{
	int a = 2 + 2;
    int b = 10 * SQUARE(a);
	//替换后:int b = 10 * ((2 + 2) * (2 + 2));
	printf("%d", b);//输出160
	return 0;
}

带副作用的参数

a + 1 //不带副作用
a++   //带副作用
#define MAX(a, b) ((a) > (b) ? (a) : (b))

int main()
{
	int a = 5;
	int b = 4;
	int c = MAX(a++, b++);
	// 替换后int c = ((a++) > (b++) ? (a++) : (b++));
	printf("%d", c);// 输出:6
	return 0;
}

「#」

 将参数名转换为字符串

#define print(x) printf("the value of "#x" is %d",x)

int main()
{
	int a = 10;
	print(a);
	//转换后:printf("the value of ""a"" is %d",x);
	//输出:the value of a is 10
	return 0;
}

「##」

 将两边符号的进行合并

#define print(a,b) printf("%d",a##b)

int main()
{
	int abc = 10;
	print(a, bc);
	//转换后:printf("%d",abc)
	//输出:10
	return 0;
}

「#undef」

移除指定宏定义

#define MAX 1000
#undef MAX //移除宏定义MAX

宏的优缺点

优点:

(1)无类型限制,更灵活

(2)直接替换,执行效率高

缺点:

(1)若宏体过大,替换时会大幅增加程序代码量

(2)无类型限制,不严谨

(3)无法调试

(4)不可使用带有副作用的参数

offsetof 模拟实现

#define OFFSETOF(type,name) (int)&(((type*)0)->name)
//将0转换为对应结构体类型,这时结构体的地址从0开始
//取出的成员地址正好就是相较于起始位置的偏移量
//由于最后求的是偏移量(整数),还需将地址转换为整型
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值