C/C++中慎用宏(#define)

  宏的定义在程序中是很是有用的,可是使用不当,就会给自身形成很大的困扰。一般这种困扰为:宏使用在计算方面。程序员

本例子主要是在宏的计算方面,不少时候,你们都知道定义一个计算的宏,对于编译和编程是多么的有用。如今定义有如下一个计算 “乘法” 的宏。编程

#include <stdio.h> #define MUL(a) ((a)*(a)*(a)) int main(int argc,char *argv[]) { int i = 10; int sum = MUL(i); printf("MUL(%d) = %d\n",i,sum); return 0; } 

  上面程序的这种作法对于非负数而言那就是没有问题的,好比,程序中的 变量 i=10,这个时候,调用宏获得的数据以下:安全

        

  可是如何变量的数值是自加或者自减的操做的话,结果就不同了。优化

  假如咱们将上面的程序变为下面这样的spa

#include <stdio.h> #define MUL(a) ((a)*(a)*(a)) int main(int argc,char *argv[]) { int i = 10; int sum = MUL(++i); printf("MUL(%d) = %d\n",i,sum); return 0; } 

  获得的结果并非 11 * 11 *11 = 1331这个数据,而是 1872,这时候有人会问为何?blog

      

  获得宏的朋友或者了解过宏在计算方面的朋友就会知道,这除了是宏的问题,仍是自己程序员编写这段代码的问题。当使用了 ++i 和 i++ 的时候,数学

要特别注意在宏中是所有使用 ++i或者i++的,变成的格式以下io

MUL(i++) ((i++)*(i++)*(i++)) MUL(++i) ((++i)*(++i)*(++i)) 

  上述的作法显然不是咱们想要的计算结果,可能在咱们程序中看到的是MUL(++i) 或者 MUL(i++),认为其实是以下状况:编译

//当i的初始化数值为10的时候,进行i++的 MUL(i++)宏计算,便是:
int i = 10;

//MUL(i ++)的数值计算结果相比是 10 * 11 * 12的,这是没有问题的,可是 i的值呢??是11吗??显然不是。

MUL(i++) = 10 * 11 *12;

i = ??;

  i的数值以下图所示class

    

  诚然,i的数值变成了 13,这是为何呢??

  那就是由于这个MUL(a)这个宏和程序员的 “自加自减” 操做所形成的。这里先普及一下 C/C++语言的 “自加自减” 操做:

//自加自减的操做 i++ 和 ++i ----> 这里的操做属于++后操做,能够替换成 i = i+1 的结果。 可是,当它赋值给一个变量的时候,表示的内容和含义就有不一样: (假设i = 10) 1. sum1 = i++; 2. sum2 = ++i; 1中的sum1的数值就是 10, i为 11 2中的sum2的数值就是 11, i为 11 这是由于: i++ 操做是 先赋值给 sum1后,本身在执行 i = i+1的操做 ++i 操做是 先进行 i = i+ 1的操做,而后再赋值给sum2 这样获得的结果固然不一样了,可是i最终的结果是要加1的,只不过是赋值给变量的时候会有不一样 

  

  经过对自加自减的操做进行说明,不知道你们是否明白为何了吗??

   

 当 i  = 10的时候,MUL(i++)就是为  (i++)*(i++)*(i++)的计算结果,考虑到C/C++的运算符结合性,

先计算第一个 i++,这是一个先计算后赋值的自加方式,那么这是后第一个 (i++)的数值待定为 10 ,那么第

二个的i是由于第一个数据的 (i++)起了做用而变化的,这时候第二个(i++)的数值为11,而后加1,这时候 根

据结合性,先计算前面两个数据,就是(i++) * (i++)的数值了,即为:10 * 11了,这时候的i数值是 12;

而后计算第三个 i++的数值,这时候第三个i++中的i数值为 12,计算后再加1,也就是说,10 * 11 * 12以后,

i= 12 的数值在进行i++变为 13了。因此  MUL(i++) = 10 * 11 * 12 = 1320。

   

  另外,在进行++i的操做和上述的状况差很少,只不过是先作自加的运算,在进行赋值。

  

当 i = 10的时候,MUL(++i)实际上也为 (++i)*(++i)*(++i)的方式,这时候先计算第一个 (++i),这是一

个先计算后赋值的结合方式,那么 i = i+1 = 11;这时候准备计算第二个(++i)的时候,由于须要先计算后赋值,

因此 第二个 ++i 以后的数值为12,可是由于i属于同一个变量和属性,那么第一个i也会变成 12了,这时候结合性

考虑应该是计算前两个(++i)的结果,再与第三个(++i)计算,即(++i)*(++i) = 12 * 12;而后,咱们计算第三个

(++i)的数值,因为前面第二个++i的i值,因此第三个++i即为 13,此时,12 * 12 * 13。  

  有人可能顾虑,为何最后不是13 * 13 * 13的呢?那不是最后都是13吗??  ------》其实这种想法是错误的,

这必须先理解运算符的结合性。咱们知道,当计算中遇到了括号的时候,咱们先计算括号的内容,这是咱们在数学中

的惯性思惟。可是对于计算机而言,计算机必须 有计算的优先级,也就是运算符的优先级问题。首先咱们计算前面两

个括号的内容,觉得两个括号之间有乘号(*),因此计算前面两个(++i)以后,必须进行乘法计算,这就是优先级中的

乘法计算,自左向右计算。因此结果变为了 12 * 12的最终结果在和第三个括号的(++i)计算,

就是144 * (++ i) = 144 * 13; 

   因此MUL(++i)的结果以下:

    

 

总结:

  慎用宏在计算方面的,可是宏的有点仍是不少的,对于C语言来讲,宏能够减小运行的时间。在C++中,宏因为不会对类型进行检查,安全性不够,因此建议使用const来

进行使用,这样能够保证类型一致。这是C/C++对宏的严谨性进行优化的结果。更多的宏的知识或者如何定义宏,你们能够上网查查资料。

相关文章
相关标签/搜索