cly

博客园 首页 新随笔 联系 订阅 管理

C语言表达式/自增运算符:int a = 4;(++a) += (a++);中a值计算的思考!

摘自:http://hi.baidu.com/tomorrowguy/blog/item/cd83cdfbb2236e7e024f5611.html

       其实说实话,这个表达式根本不具有实用性,而且其很有可能在不同的编译器下有着不同的解释,从而运行出不同的结果,极其不推荐使用这种写法,当然如果你想知道清楚,那希望你有耐心看我我的东西。。。

    首先给出我的测试结果:

测试代码:

 #include<stdio.h>

void main()

{

 inta=4,b=4,c=4,d=4,e=4,f=4,g=4,h=4,j=4;

 a+= (a++);

 e=e+(e++);

 b+= (++b);

 d=d+(++d);

 (++c)+=(c++);

 (++f)=(++f)+(f++);

 (++h)=(++h)+(++h);

 (++j)=(j++)+(j++);

 (++g)+=(++g);

 printf("%d,%d,%d,%d,%d,%d,%d,%d,%d",a,e,b,d,c,f,h,j,g);

}

测试结果:

a=9;e=9

b=10;d=10

c=11;f=13

h=14;j=12

g=12

注:以上结果基于vc6.0编译器。

下面提下细节问题:

(++a) += (a++)不等价于 (++a)=(++a)+(a++)  !!!

(注:基于vc6.0,其他编译器我不知道,待定。同时可以说明表达式中的此类括号的存在与否在vc6.0中是没有影响的,这个也因编译器而定。以后不再特别说明)

      根据测试结果: (++c)+=(c++) 为11 ;(++f)=(++f)+(f++)为13  。可知两者其实并不等价,因为两者的算法不同,详见下面。

     下面我提出我的基本观点: 前置自增运算符在一个表达式中其优先级是很高的,一般情形下,在一个算术运算表达式中其具有最高优先级。

若一个算术表达式f(++a1,++a2,++...,++an)中含有n个前置自增运算符,则此表达式的求解过程等价于:

++a1;

++a2;

 ++a3;

........

++an;

f(a1,a2,a3,...,an);//注意表达式的变化:f(++a1,++a2,++...,++an) 变为 f(a1,a2,a3,...,an)

      下面讨论含有后置自增运算符时的情形,后置自增作用的变量是先用后增,从而若有一个算式表达式f(b1++,b2++,...++,bn++)中含有n个后置自增运算符,则此表达式的求解过程等价于:

f(b1,b2,b3,...,bn);

b1++;

b2++;

b3++;

........

bn++;

      进一步拓展为: 若一个算式表达式f(++a1,++a2,++...,++an,b1++,b2++,...++,bn++)中含有n个前置自增运算符,和含有n个后置自增运算符,则此表达式的求解过程等价于:

++a1;

++a2;

++a3;

........

++an;

f(a1,a2,a3,...,an,b1,b2,b3,...bn);

b1++;

b2++;

b3++;

........

bn++;

 下面举例证明:

1 :(++a) += (a++) 等价于:

++a;为5

a+=a;为a=10

a++;为11

 2: (++f)=(++f)+(f++)等价于:

++f;为5

++f;为6

f=f+f;为12

f++;为13

其他各式都可如此证明,至此,证毕!

     下面对此类表达式的语法进行初步讨论: 在表达式f(++a1,++a2,++...,++an,b1++,b2++,...++,bn++)中,并不是所有的情形都是能够通过编译的,那就是:在运算符=或+=等等,运算符的左边的单变量只能含有前置自增运算符,不能为带后置自增运算符的单变量,

即是说:

 (++f)=(++f)+(f++);是合法的,

(f++)=(++f)+(f++);是非法的!!!

     这个的具体机理我不知道,但是初步猜测为: 在左侧为前置自增运算符时,其自增计算在表达式的计算之前完成了,从而在计算表达式的值时此时左侧已经成为了单值变量,而不再是表达式,但是当左侧为后置自增运算符时,其在计算表达式的值时自增运算还没有进行,左侧为表达式,从而语法错误。 基于以上讨论,第三个表达式的使用是极力不推荐的!!!

      下面给出能够通过编译的此类表达通式的计算等价形式:

表达式:++Value+=f(++a1,++a2,++...,++an,b1++,b2++,...++,bn++)的等价计算为:

++Value;

++a1;

++a2;

++a3;

 ........

++an;

Value=Value+f(a1,a2,a3,...,an,b1,b2,b3,...bn);

b1++;

b2++;

b3++;

........

bn++;

至此,完毕,谢谢阅读~~~

写在最后:此题目来源于一位百度知道的网友的提问,对在此引用其题目注以说明!

以下为本人补充的汇编代码:

View Code
 1 1:    #include <iostream>
 2 2:
 3 3:    using namespace std;
 4 4:
 5 5:    void addSelf()
 6 6:    {
 7 00402AF0   push        ebp
 8 00402AF1   mov         ebp,esp
 9 00402AF3   sub         esp,44h
10 00402AF6   push        ebx
11 00402AF7   push        esi
12 00402AF8   push        edi
13 00402AF9   lea         edi,[ebp-44h]
14 00402AFC   mov         ecx,11h
15 00402B01   mov         eax,0CCCCCCCCh
16 00402B06   rep stos    dword ptr [edi]
17 7:        int a = 4;
18 00402B08   mov         dword ptr [ebp-4],4
19 8:
20 9:        (++a) += (a++);
21 00402B0F   mov         eax,dword ptr [ebp-4]  4+1
22 00402B12   add         eax,1
23 00402B15   mov         dword ptr [ebp-4],eax  a=5
24 00402B18   mov         ecx,dword ptr [ebp-4] 
25 00402B1B   add         ecx,dword ptr [ebp-4]  5+5
26 00402B1E   mov         dword ptr [ebp-4],ecx  a=10
27 00402B21   mov         edx,dword ptr [ebp-4]
28 00402B24   add         edx,1                  a=a+1:a=10+1,即a=11
29 00402B27   mov         dword ptr [ebp-4],edx

 

posted on 2012-07-11 23:19  戒色  阅读(1640)  评论(0编辑  收藏  举报