回 帖 发 新 帖 刷新版面

主题:转帖!让c语言和c++中的“a++,++a”永远不是问题

这里主要研究一下c语言和c++中的a++,++a
有分双操做数和多操做数之分
双操做数:
在语言中定义a++是先用后加,++a是先加后用。
实际上对双操做数来说的是在一个语句中结束前加和后加的问题 。
即如k=(++a)+(a++);
a++是语句结束后在后加,
++a是先加后计算再语句结束。

我举几个例子(用反汇编说明)
1 int k=2;
int val=0;
val=(k++)+(k++);

反汇编
8: int k=2;
00401028 mov dword ptr [ebp-4],2//// k的地址是dword ptr [ebp-4]
9: int val=0;
0040102F mov dword ptr [ebp-8],0//val的地址是dword ptr [ebp-8]
10: val=(k++)+(k++);
00401036 mov eax,dword ptr [ebp-4]// 把2放入eax中
00401039 add eax,dword ptr [ebp-4]// 把2+2=4放入eax中
0040103C mov dword ptr [ebp-8],eax//把eax中的4移回val中
0040103F mov ecx,dword ptr [ebp-4]
00401042 add ecx,1//
00401045 mov dword ptr [ebp-4],ecx//k地址中的值加1,k=3

00401048 mov edx,dword ptr [ebp-4]
0040104B add edx,1// 寄存器中的值加1,k=4
0040104E mov dword ptr [ebp-4],edx//移回k地址

结论:val=*( dword ptr [ebp-8])=4;k=4

2. int k=2;
int val=0;
k=(k++)+(k++);

反汇编
:
8: int k=2;
00401028 mov dword ptr [ebp-4],2//同上
9: int val=0;
0040102F mov dword ptr [ebp-8],0
10: k=(k++)+(k++);
00401036 mov eax,dword ptr [ebp-4]
00401039 add eax,dword ptr [ebp-4] //同上
0040103C mov dword ptr [ebp-4],eax//同上,不同的是计算结果存入k地址k=4
0040103F mov ecx,dword ptr [ebp-4]
00401042 add ecx,1//寄存器中的值加1,
00401045 mov dword ptr [ebp-4],ecx//k=5
00401048 mov edx,dword ptr [ebp-4]
0040104B add edx,1//寄存器中的值加1
0040104E mov dword ptr [ebp-4],edx//k=6

结论:k=*( dword ptr [ebp-4])=6;

3 int k=2;
int val=0;
val=(++k)+(++k);

反汇编:
8: int k=2;
00401028 mov dword ptr [ebp-4],2// k的地址是dword ptr [ebp-4]
9: int val=0;
0040102F mov dword ptr [ebp-8],0//val的地址是dword ptr [ebp-8]
10: val=(++k)+(++k);//k先加
00401036 mov eax,dword ptr [ebp-4]
00401039 add eax,1//寄存器中的值加1

0040103C mov dword ptr [ebp-4],eax//k=3
0040103F mov ecx,dword ptr [ebp-4]
00401042 add ecx,1//对k地址中的值加1,k=4
00401045 mov dword ptr [ebp-4],ecx
00401048 mov edx,dword ptr [ebp-4]
0040104B add edx,dword ptr [ebp-4]//k+k=8
0040104E mov dword ptr [ebp-8],edx//值移入val地址中val=8

结论:val=*( dword ptr [ebp-8])=8;k=4
4. int k=2;
int val=0;
k=(++k)+(++k);
反汇编:
8: int k=2;
00401028 mov dword ptr [ebp-4],2
9: int val=0;
0040102F mov dword ptr [ebp-8],0
10: k=(++k)+(++k);
00401036 mov eax,dword ptr [ebp-4]
00401039 add eax,1
0040103C mov dword ptr [ebp-4],eax
0040103F mov ecx,dword ptr [ebp-4]
00401042 add ecx,1
00401045 mov dword ptr [ebp-4],ecx
00401048 mov edx,dword ptr [ebp-4]
0040104B add edx,dword ptr [ebp-4]///以上同3例
0040104E mov dword ptr [ebp-4],edx// 值移入k地址k=8
结论:k=*( dword ptr [ebp-4])=8;

5. int k=2;
int val=0;
val=(++k)+(k++);

反汇编:


8: int k=2;
00401028 mov dword ptr [ebp-4],2
9: int val=0;
0040102F mov dword ptr [ebp-8],0
10: val=(++k)+(k++);
00401036 mov eax,dword ptr [ebp-4]
00401039 add eax,1
0040103C mov dword ptr [ebp-4],eax//k=k+1=3
0040103F mov ecx,dword ptr [ebp-4]
00401042 add ecx,dword ptr [ebp-4]//k+k=6
00401045 mov dword ptr [ebp-8],ecx//val=6
00401048 mov edx,dword ptr [ebp-4]
0040104B add edx,1//k=k+1=4
0040104E mov dword ptr [ebp-4],edx

结论:val=*( dword ptr [ebp-8])=6;k=4

6. int k=2;
int val=0;
k=(++k)+(k++);

反汇编:

8: int k=2;
00401028 mov dword ptr [ebp-4],2
9: int val=0;
0040102F mov dword ptr [ebp-8],0
10: k=(++k)+(k++);
00401036 mov eax,dword ptr [ebp-4]
00401039 add eax,1//k+1
0040103C mov dword ptr [ebp-4],eax//k=3
0040103F mov ecx,dword ptr [ebp-4]
00401042 add ecx,dword ptr [ebp-4]//k+k=6
00401045 mov dword ptr [ebp-4],ecx//k=6
00401048 mov edx,dword ptr [ebp-4]
0040104B add edx,1
0040104E mov dword ptr [ebp-4],edx//k=k+1=7

结论:k=*( dword ptr [ebp-4])=7;k=7

多操做数

多操做数(>2)头两个操做数同以上(中间值)而后面的数如是(++i)加1
如是(i++)不加1。赋值给变量如果不是本身则结束
如果是本身则要数(i++)个数如是n加n
举几个例子
1.
int k=2;
int val=0;
val=(k++)+(k++)+(++k);

反汇编:

331: int k=2;
00407488 mov dword ptr [ebp-14h],2
332: int val=0;
0040748F mov dword ptr [ebp-18h],0
333: val=(k++)+(k++)+(++k);
00407496 mov eax,dword ptr [ebp-14h]
00407499 add eax,dword ptr [ebp-14h]//以上同双操做数中间数存在eax中eax=4,k=2
0040749C mov ecx,dword ptr [ebp-14h]
0040749F add ecx,1
004074A2 mov dword ptr [ebp-14h],ecx//k=3
004074A5 add eax,dword ptr [ebp-14h]//eax+k=
004074A8 mov dword ptr [ebp-18h],eax//赋值给val=eax+k=7
004074AB mov edx,dword ptr [ebp-14h]
004074AE add edx,1
004074B1 mov dword ptr [ebp-14h],edx
004074B4 mov eax,dword ptr [ebp-14h]
004074B7 add eax,1
004074BA mov dword ptr [ebp-14h],eax

结论:val=*( dword ptr [ebp-18h])=6;k=5

2.
int k=2;
int val=0;
k=(k++)+(k++)+(++k);
反汇编:


331: int k=2;
00407488 mov dword ptr [ebp-14h],2
332: int val=0;
0040748F mov dword ptr [ebp-18h],0
333: k=(k++)+(k++)+(++k);
00407496 mov eax,dword ptr [ebp-14h]
00407499 add eax,dword ptr [ebp-14h]
0040749C mov ecx,dword ptr [ebp-14h]
0040749F add ecx,1
004074A2 mov dword ptr [ebp-14h],ecx
004074A5 add eax,dword ptr [ebp-14h]
004074A8 mov dword ptr [ebp-14h],eax//赋值给k=eax+k=7
004074AB mov edx,dword ptr [ebp-14h]
004074AE add edx,1
004074B1 mov dword ptr [ebp-14h],edx//k=k+1=8
004074B4 mov eax,dword ptr [ebp-14h]
004074B7 add eax,1
004074BA mov dword ptr [ebp-14h],eax//k=k+1=9

结论:val=*( dword ptr [ebp-14h])=9;

举个题
1.
int k=2;
int val =0;
val=(++k)+(++k)+(k++)+(++k) +(++k) +(++k) +(++k) +(k++)+(k++)+(k++);
val=4 + 4 +4 +5 +6 +7 +8 +8 +8 +8= 62

2.
int k=2;
k=(++k)+(++k)+(k++)+(++k) +(++k) +(++k) +(++k) +(k++)+(k++)+(k++);
4个k++
k=4 + 4+ 4 +5 +6 + 7 + 8 +8 +8 +8 在加 4=66


"a--,--a"与++a,a++相同.
欢迎到群来交流:4231894  
VC6.0下通过验证!!!!!!!!!!!!!

回复列表 (共11个回复)

沙发

板凳

win me  + win-tc 2.0


1.
main()
{
int k=2;
int val =0;
val=(++k)+(++k)+(k++)+(++k) +(++k) +(++k) +(++k) +(k++)+(k++)+(k++);
printf("%d",val);
}

结果:
80


2。

main()
{
int k=2;

k=(++k)+(++k)+(k++)+(++k) +(++k) +(++k) +(++k) +(k++)+(k++)+(k++);
printf("%d",k);
}


结果:
84


3 楼

win xp  + vc6.0+tc3.0
1.#include<iostream.h>
void main()
{
int k=2;
int val =0;
val=(++k)+(++k)+(k++)+(++k) +(++k) +(++k) +(++k) +(k++)+(k++)+(k++);
cout<<val;}
val=4 + 4 +4 +5 +6 +7 +8 +8 +8 +8= 62

2. #include<iostream.h>
void main()
{
int k=2;
k=(++k)+(++k)+(k++)+(++k) +(++k) +(++k) +(++k) +(k++)+(k++)+(k++);
cout<<k;}
4个k++
k=4 + 4+ 4 +5 +6 + 7 + 8 +8 +8 +8 在加 4=66

4 楼

win xp  + vc6.0+tc3.0
1.#include<iostream.h>
void main()
{
int k=2;
int val =0;
val=(++k)+(++k)+(k++)+(++k) +(++k) +(++k) +(++k) +(k++)+(k++)+(k++);
cout<<val;}
val=4 + 4 +4 +5 +6 +7 +8 +8 +8 +8= 62

2. #include<iostream.h>
void main()
{
int k=2;
k=(++k)+(++k)+(k++)+(++k) +(++k) +(++k) +(++k) +(k++)+(k++)+(k++);
cout<<k;}
4个k++
k=4 + 4+ 4 +5 +6 + 7 + 8 +8 +8 +8 在加 4=66

5 楼

6 楼

所以,这个问题不用“研究”,不同的编译器得出的结果是不同的,而且在实际应用中根本就没人这么用++,--。

7 楼

楼上说得很对..
这些就是纯抠语法,没有丝毫的意义..
会诱导人死钻牛角尖的..

8 楼

但考试就爱考这样的题

9 楼

*( dword ptr [ebp-8]) 我学用汇编2年多了还没见过这样不论不类的表达式
写的很好,不过不是我打击你,在现实编程中这没有任何用处,编译器用多了试一下就可以,如果你在你的程序用了这样的表达式,你的老板第一个开除的就是你!

10 楼

运用中不用++ 和-- 不会吧!1!!!!!那我就不用把他搞的这么清楚了[em1]

我来回复

您尚未登录,请登录后再回复。点此登录或注册