LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
楼主: sfiloveyou

请教一道编程题?

[复制链接]
发表于 2004-12-3 01:23:16 | 显示全部楼层
最初由 hupeng923 发表
这样的问题我上次发过的,,在不同的编译器上结果不同。在 TC 上的结果比较符合老教材的讲解。我还没试过,但我想在TC上的结果应该是k=19, a=8吧。
k=5+7+7
(不一定对)

你说的是楼主的?
是18,我试验了,在TC上应该和crquan兄说的一样
发表于 2004-12-3 01:29:11 | 显示全部楼层
楼顶的,是19,8。
头晕,呵呵
发表于 2004-12-3 01:34:01 | 显示全部楼层
最初由 hupeng923 发表
楼顶的,是19,8。
头晕,呵呵

我刚运行了,是18,8的
发表于 2004-12-3 01:38:11 | 显示全部楼层
我打错了,呵呵,有限头晕。可我不知道错在哪儿:
第一个括号里应该取a先前的值5(改变后是6), 第二个取改变后的值7, 第三个取改变前的值7。。。但结果确不对

k=(a++)+(++a)+(a++);
发表于 2004-12-3 01:48:15 | 显示全部楼层

回复: 回复: 请教一道编程题?

最初由 crquan 发表
是这样的:
  • 在函数调用中从右到左计算参数;
  • 在表达式中所有参数一起计算;

如:

  1.         k=(a++)+(++a)+(a++);
复制代码

式中有 (++a) 为表达式前计算,此时 a=6,两个 (a++) 为表达式后计算,此时计算 k=6+6+6=18,再做两个 (a++) 后 a=8。
发表于 2004-12-3 01:53:04 | 显示全部楼层
找到一篇文章,
http://www.20cn.net/ns/wz/comp/data/20040109011054.htm

分双操作数和多操作数两大类,跟大家说的都不太一样
发表于 2004-12-3 01:56:46 | 显示全部楼层
[PHP]您正在查找的页当前不可用。 网站可能遇到支持问题,或者您需要 调整您的浏览器设置。[/PHP]
能不能贴出来?
发表于 2004-12-3 02:00:08 | 显示全部楼层
不错!
--------------------------
让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;
int val =0;
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++相同.
版权属于原创作者!!!
=========================
文章类型:转载 提交:啥都不会 核查:NetDemon
发表于 2004-12-3 02:25:26 | 显示全部楼层
最初由 hupeng923 发表
1 int k=2;
int val=0;
val=(k++)+(k++);
结论:val=*( dword ptr [ebp-8])=4;k=4
——都懂
2. int k=2;
int val=0;
k=(k++)+(k++);
结论:k=*( dword ptr [ebp-4])=6;
——也懂
3 int k=2;
int val=0;
val=(++k)+(++k);
结论:val=*( dword ptr [ebp-8])=8;k=4
——懂
4. int k=2;
int val=0;
k=(++k)+(++k);
结论:k=*( dword ptr [ebp-4])=8;
——懂
5. int k=2;
int val=0;
val=(++k)+(k++);
结论:val=*( dword ptr [ebp-8])=6;k=4
——懂
6. int k=2;
int val=0;
k=(++k)+(k++);
结论: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);
004074A8 mov dword ptr [ebp-18h],eax//赋值给val=eax+k=7
结论:val=*( dword ptr [ebp-18h])=6;k=5
——有问题,val既然已经是7了,最后怎么变6了?我认为应该是7
2.
int k=2;
int val=0;
k=(k++)+(k++)+(++k);
结论:val=*( dword ptr [ebp-14h])=9;
——懂,和上边一样,所以我认为上一个是写错了,应该是7

我觉得他的结论和我之前用GCC通过试验分析的结论相同
发表于 2004-12-3 02:40:15 | 显示全部楼层
嗯,他的关于取值顺序的结论很有用
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表