a = 0, a = (++a) + (++a) + (++a) + (++a), a = ?
今天在参与的C/C++小组中,看到了这道题目,或许有的人会说它变态,毫无意义,但做为消遣想想又有何妨呢?况且还能加深对C++某些语法的理解。
这题的解答过程如下:
假设a在内存栈中的存储简单表示为---> |0|(表示此时内存中a的值)
第一次++a,那么便访问存储器,将a自增1,即a=1
第二次++a,再次访问存储器,将a自增,即a=2
==>这时要将前后两次的结果相加,注意:做加法的过程,如c=a+b,是分别取出a的值以及b的值,然后再利用加法器(貌似是这么叫的)将计算的结果放入c中。所以此时我们可以看出,(++a)+ (++a)两括号中间的加号两边的值是2!!!,因为整个过程大概是这样的:() + (), 先让括号中的表达式先计算好,然后再利用两个括号计算的结果做加法。但是,这里,两个括号其实都是在存储a的那个内存上操作,所以最后取出来的结果都是一样:2。所以前两个相加为4,存储在一个临时的地址中。
第三次++a,此时a = 3,与前面的结果做加法,得4+3=7
第四次++a,此时a = 4,与前面的结果做加法,得7+4=11
所以a = 0, a = (++a) + (++a) + (++a) + (++a), a = 11.
写到这里,可能有人会怀疑,括号的不是要比加号的优先级要高?那是否应该先算完4个括号中的内容,再做剩下的加法呢?解答这个问题很简单,比如看如下过程
1+2+3*4+5,乘法的优先级高于加法,是否应该先算呢?确实,它先算是对的,但它后算也没影响。在这种表达式的求解中,我们可以利用逆波兰式(貌似是这么叫的-_-!!!): 1_2_+_3_4_*_+_5_+。从逆波兰式可以看出,1跟2的加法是可以先算的,不影响最后的结果。
终于写完了。。。第一次写博客。。。感觉废话很多。。。
而且没有学过编译原理,组成原理,有些东西都说得不够地道。。sigh。。。
David Cai, 2009年7月4日于实验室