毕业论文
您现在的位置: 语言识别 >> 语言识别介绍 >> 正文 >> 正文

在C语言程序中使用临时中间变量,会不会降

来源:语言识别 时间:2024/12/20
在C语言程序开发中,有时为了一行代码不至于过长,或者其他原因,程序员常常会使用一些临时的中间变量,使用临时中间变量的C语言代码,大都可以抽象成类似于下面这样的例子,请看:inti=5;intj=10;intresult=i+j;有些小伙伴就有疑问了到这里,有些小伙伴就有疑问了,使用临时中间变量会降低C语言程序的效率吗?或者说,将上面的3行代码写成一行:intresult=5+10;是否能够得到更高效率的C语言程序呢?鉴于使用临时中间变量常常能够提升代码的可读性,要是它同时真的会降低程序效率,我们就陷入矛盾了。究竟有没有必要使用长表达式,代替临时中间变量呢?其实,绝大多数现代C语言编译器已经足够聪明,优化上述代码轻而易举。我们还是以上述C语言代码为例,对其稍作调整,相关代码如下,请看:以gcc编译器为例,添加-std=c99指定C99标准,并指定-O3优化项,应该能够得到上述C语言代码对应的汇编代码:movl$15,%esiC语言编译器常用的一个策略“constantpropagation(常数传播,下文讨论)”会将i+j在编译阶段计算完毕。另外值得说明的是,我在上述C语言代码中添加了printf()函数读取result,否则fun()函数将直接被优化成下面这样的汇编代码:func:repret机器甚至都不会再去计算和保存i+j,直接就返回了。C语言编译器做出这样的优化,显然可以避免无效代码消耗机器性能,因为fun()函数中并无实际的代码要用到result,再去计算和处理它,显然就是做无用功。当然了,若是考虑到硬件寄存器,即使没有代码使用到result,对其赋值也可能是有意义的。这是就需要一些其他操作,来避免编译器优化了。这一点,我之前的文章讨论过,感到陌生的读者可以翻翻看看。优化它们轻而易举可见,即使在C语言代码中使用了一些临时的中间变量,也不用太过担心它们会影响效率,因为这对于编译器来说,优化它们轻而易举。编译器的“常数传播”和“常数折叠”策略考虑到一些初学者不太熟悉编译器的策略,这里对前文设计的“常数传播”策略稍作解释。常数折叠(Constantfolding)以及常数传播(constantpropagation)都是C语言编译器对代码做优化使用的策略之一。“常数折叠”是在编译期间简化常数的过程。常数在C语言程序中仅仅代表一个简单的数值,事实上,若某个变量从未被修改,完全可以将其也当作常数,请看下面这个例子:i=**32;多数现代C语言编译器不会真的产生两个乘法指令,然后再将结果存储起来,而是辨识是否之后没有代码修改变量i,若如此,则会在编译阶段就将结果计算出来,之后直接使用计算结果。此即一次典型的“常数折叠”过程,这样做显然可以减小C语言代码尺寸,并且能够得到更高效的程序。得到更高效的程序“常数传播”则是一个替代表达式中已知常数的过程,也是在编译时执行的,这里仍然以实例讨论,请看下面这段C语言代码:intx=14;inty=7-x/2;returny*(28/x+2);编译器执行“常数传播”策略,则x会被替换为常数14,得到下面这样的C语言代码:intx=14;inty=7-14/2;returny*(28/14+2);编译器通常还会执行一些消除无用代码的继续这一传播过程,则最终得到下面这样的C语言代码:intx=14;inty=0;return0;编译器通常还会执行一些消除无用代码的过程,以对整个C语言程序优化,因此在现代编译器看来:intx=14;inty=7-x/2;returny*(28/x+2);其实和简单的return0;没什么两样。小结本文在最后介绍了现代C语言编译器常用的“常数折叠”和“常数传播”策略,可见,如今的编译器早已不再是只会逐行“死板”的处理代码了,因此,我们在编写C语言代码时,除非在某些特殊的情况下,否则更多的应该关心代码的可读性。那些复杂的“优化”工作,交给编译器去做就好了。点个

转载请注明:http://www.0431gb208.com/sjszlfa/8120.html