#define 定义常量 与 定义 宏

目录

文章目录

前言

一、#define机制

二、宏与函数的对比

1.宏对比函数的优点

2.宏对比函数的劣势



前言

提起预处理,第一时间想到的大多都是类似于头文件的引入,但这里面其实大有可说。

比如:

    printf("%s\n", __DATE__);
    printf("%s\n", __TIME__);

这是编译器自己设置的⼀些预定义符号,无需定义可以直接使⽤现在问:这些printf打印出了什么内容?


一、#define机制

1.#define 定 义 常 量

#define MAX 0

编译器看到这行代码后,会把使后续代码中除了字符串中的MAX,其余出现的MAX都会被替换成“0”,比如“printf("MAX=%d",MAX);”——>“printf("MAX=%d",0);"

作者在学到这时曾有疑问:#define MAX 0后面需要加“;”吗?看上去加不加似乎都无伤大雅,

但作者建议不要在#define语句后加上“;”,就拿上面的那条语句说:若是在后面加上“;“变成#define MAX 0;

那编译器在编译printf("MAX=%d",MAX);时就会报错,原因是在预处理阶段MAX已经被替换成“0;”了,相当于printf("MAX=%d",0;);   显然这里出现了语法错误。

以下代码报错的原因是?

#define X 7;
int main()

{
    int a = 0;
    if (1)

        a = X;

    else

        printf("goodby");

}

if-else语句如果没加{}则每个只能写一条语句,即只能有一个“;”,这里的X自带一个";",后面又加一个“;”,故编译器报错。

现在接前言:

__DATE__,其值是执行这段程序的日期;

__TIME__是执行这段代码的时间;

除此之外还有__FILE__,值是当前文件所在目录;

__LINE__,值是当前代码行数。

等等...

注意:在使用#define时有个不成文的规定,名字一般都为大写

2.#define 定 义 宏

规则:#define定义机制允许把参数也替换到文本中

比如:

#define SQU(x)  x*x

注意:参数的左括号需与名紧密相接,不能有空号。现在可以在文中使用以下代码:

int x=2;

int z =SQU(x);

printf("%d",z);

原理是:编译器会在预处理阶段把SQU(x)替换为x*x。 所以打印出的 z的值 自然是 4。

但这样做也是有风险的

请考虑将上述第二行代码转变为int z = SQU(2 + 1);  ,这样z的值会是多少呢?9吗?

我们顺着思路将int z = SQU(2 + 1);替换为编译器处理过后的内容:int z =2 + 1 * 2 + 1;

现在明确了,原来是运算符的先后次序不同导致的,解决这个问题:在宏定义上加上两个括号就可以了。

#define SQU(x)  (x)*(x)

再看以下代码未实现目标的原因:

#define ADD(x)   (x)+(x)

int a = 5;

int b = 10 * ADD(5);

printf("%d",b);

b的结果是55,而不是100。编译器处理后变成了int b = 10 * (5)+(5);

改为#define ADD(x)   ((x)+(x))这样定义即可。

作者建议在定义宏时不 要 吝 惜 括号“()”。

二、宏与函数的对比

认识了宏后感觉宏与函数非常相似,那么他们的区别是?

#define MAX(a,b) ((a)>(b)?(a):(b))
int main()
{
	int z = MAX(3, 5);
	printf("%d", z);
	return 0;
}

上述代码是定义成宏好呢,还是封装成函数好呢?

1.宏对比函数的优点

1.所耗时间少:若使用函数实现上述代码,则函数的调用、参数的传递、函数的返回所用的时间是大于用宏实现该段代码的,毕竟使用宏时编译系统是直接把代码“复制粘贴”在原处。所以宏在

2.无需重复定义函数:函数参数的类型决定了该函数的使用范围,若形参为int型,则float型数据就无法使用该函数,,而使用宏是与参数类型无关的,没有这种顾虑。

2.宏对比函数的劣势

1.宏无法调试:在明白宏生效的途径后,当即明白宏是没办法调试的。

2.宏会大幅增加代码长度:若是每调用一次宏,编译器就“复制粘贴”一份,那代码的长度将会大幅增加,给维护带来不便。

请看以下代码 

#define MAX(a,b) ((a)>(b)?(a):(b))
int main()
{
	int x = 3, y = 5;
	int z = MAX(x++, y++);
	printf("x=%d y=%d z=%d",x,y,z);

	return 0;
}

这段代码完成后,x=4,y=7,z=6;

3.宏可能会带来运算符优先级的问题以及永久改变参数值的问题

但宏有时能做到函数难以完成的事:

#include<stdlib.h>
#include<stdio.h>
#define MALLOC(num,type) (type*)malloc(num,sizeof(type))
int main()
{
	int* pf = MALLOC(3, int);
	if (pf == NULL)
	{
		return 1;
	}
	free(pf);
	pf = NULL;
	return 0;
}

这里编译器预处理之后变成:int * pf=(int*) malloc(3,sizeof(int));


  • 47
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值