C – #define理解

最近学习C语言吧,看的是C程序设计语言一书,今天正好看到了C预处理那里,说到了这个#define A B。

首先这个叫做宏替换。那么以后你的程序里面写A的地方 其实就是B。

编译器在编译的时候会自动把A替换成B,而且是逐字替换。注意我说的这个逐字替换。

首先我们得知道在C里面怎么定义常量。那就是

1 #define strHello "HelloWorld\n"

而C++里面:

1 const string strHello = "HelloWorld\n";

这里C++里面也可以用#define来定义常量,但这只是为了兼容C。

C里面也有const关键字,但这是用来修饰函数的参数不能被修改,而不是定义常量。

在C里面#define 用得比较多是用来替换一段代码。比如:

1 #define sayMyHello() printf("Hello,HuangJacky")2 3  int main()4 {5     sayMyHello;6     return;7 }

在编译的时候,编译器会悄悄把sayMyHello替换成后面那句printf,你是不会发现的。

也就是说编译器实际上是在编译下面这段代码:

1 int main()2 {3     printf("Hello,HuangJacky");4     return;5 }

这就是替换的意思。但是我们之前说的逐字替换。解释逐字替换之前我们先来看个例子:

1 #define power2(A) A*A2 3  int main()4 {5     int i = 3;6     int j = power2(i+2);7     return;8 }

power2是求平方。那么执行到第7行的时候 j等于多少呢?j=25么?

答案是j=11;为什么?

我们来看:首先A=i+2, 而j=AA=i+2i+2=3+2*3+2=11

看到什么没有?它只是将A替换成了i+2,而没有把i+2当成一个整体,又由于算术优先级的关系,所以结果就出现了误差。

那么我们该怎么修改?

1 #define power2(A) (A)*(A)

现在j=(i+2)*(i+2)=25了。

这是当年一个台湾公司的笔试题。

就这么就完了么?还有一个需要注意的地方。。。

1 #define max(A,B) ((A)>(B))?(A):(B)2 3  int main()4 {5     int i = 3;6     int j = 2;7     int n = max(i++,j++);8     return;9 }

请问执行到第8行时 i,j,n分别是多少?

i=5,j=3,n=4;

想明白为什么没有?

我们将上面逐字替换就知道了。

1 n=((i++)>(j++))?(i++):(j++);

首先在比较的时候(i++)>(j++) 这个时候i=3,j=2,所以结果是true。

有了比较结果的时候由于自增运算符的缘故,现在i=4,j=3了。

比较结果是真,所以去返回三元运算符中的(i++),所以是4。

当返回后,由于自增运算符的缘故,这时i=5了。

从上面的例子我们可以看出来当宏替换的时候,虽然有括号括起来了,运算中出现了多少次A,程序就对A这个表达式执行了多少次。

上面这个例子中A出现了两次,其中比较的时候一次和返回的时候一次。所以最后i=5。

上面说了这么多#define使用时注意的地方,其实这些功能都能定义一个函数来完成,而且还不会出现上面这些问题。但是使用宏替换能节约调用函数时的堆栈开销。

最后记住 编译的时候,编译器会逐字的把宏替换的地方给换回去,然后编译。宏替换只是为了让我们节约一些写代码的时间和让代码阅读更方便。
原文链接: https://www.cnblogs.com/huangjacky/archive/2010/11/25/1888032.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/17879

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月7日 下午6:34
下一篇 2023年2月7日 下午6:34

相关推荐