最近学习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
非原创文章文中已经注明原地址,如有侵权,联系删除
关注公众号【高性能架构探索】,第一时间获取最新文章
转载文章受原作者版权保护。转载请注明原作者出处!