宏函数

宏函数首先它是一种宏,然后它是一种类似于函数的宏,但它与正规函数不同的是,正规函数生成的是汇编代码,而宏函数生成的是高级编程语言。因此,宏函数在使用时总会有与直观不符的情况。
OK,下面我们来看一个例子:(来自于《程序员面试宝典》)

#define SUB(x,y) x-y
#define ACCESS_BEFORE(element,offset,value) *SUB(&element,offset)=value;
int main(){
    int i;int array[10]={1,2,3,4,5,6,7,8,9,10};
    ACCESS_BEFORE(array[5],4,6);
    for(i=0;i<10;++i){printf("%d",array[i]);}
    return 0;
}   

同学们经过一翻曲折而不复杂的计算,然后嘴角上扬,不屑地说道{1,6,3,4,5,6,7,8,9,10}!
呵呵,too yang too naive!
说了,宏函数生成的是编程语言,你不能拿正规函数的逻辑去思考它,你要老老实实地把它转换成C/C++,然后再分析生成的C/C++语句会执行得出什么样的结果。
OK,开始我们的分析!
首先,ACCESS_BEFORE(array[5],4,6)会生成新的宏:*SUB(array[5],4)=6。
然后,新的宏再进行第二次替换,生成*array[5]-4=6;
最后,执行*array[5]-4=6;你猜,会是什么结果?
结果是:在某些不够优秀的编译器上,程序可以正确编译,但是运行时会崩溃。在一些足够优秀的编译器上,比如VC++上,直接就会报告语法错误。
到这里,我想大家已经知道为什么会崩溃了,因为它最后生成的编程语言是让一个右值赋给一个右值。这与我们正常函数的调用明显不符,所以在使用宏函数的时候一定要踏踏实实,一步步分析它的结果,或者,干脆就别用宏函数了,这东西正在被逐渐淘汰。

猜你喜欢

转载自blog.csdn.net/qq_36946274/article/details/80894157
今日推荐