运算符优先级?计算顺序?编译器优化?

superliu1122 2011-08-01 02:23:28

#include <stdio.h>

int P(const char* ch)
{
printf("%s\n",ch);
return 0;
}

int main(int argc, char* argv[])
{
char str[][10] = {"第一项","第二项"};
int i = 0;
int b = P(str[i++]) + P(str[i++]);
getchar();
return 0;
}

谁能说出上面的程序会输出什么
最近不小心写出了类似的代码,于是悲剧了
...全文
174 点赞 收藏 18
写回复
18 条回复
风吹PP凉SS 2011年08月01日
为什么同样是VC6,输出还不一样[Quote=引用 9 楼 superliu1122 的回复:]
VC2005、2008、2010 Debug:

第二项
第一项

VC2005、2008、2010 Release:

第一项
第一项

VC6 Debug:
第一项
第二项

VC6 Release:
第二项
第一项

MingW32
第一项
第二项
[/Quote]
回复 点赞
Jxiaoshen 2011年08月01日
[Quote=引用 12 楼 babilife 的回复:]
所以,这个如上所述,看具体编译器入栈的顺序了,没啥好讨论的了
楼主可以结贴了
[/Quote]

++是老问题 和编译环境相关
回复 点赞
赵4老师 2011年08月01日
不要迷信书、考题、老师、回帖;
要迷信CPU、编译器、调试器、运行结果。

不要写连自己也预测不了结果的代码!
回复 点赞
superliu1122 2011年08月01日
其实我只要是想知道Release和Debug为什么会有这么大区别,如果是优化的话有什么规则呢
[Quote=引用 9 楼 superliu1122 的回复:]

VC2005、2008、2010 Debug:

第二项
第一项

VC2005、2008、2010 Release:

第一项
第一项

VC6 Debug:
第一项
第二项

VC6 Release:
第二项
第一项

MingW32
第一项
第二项
[/Quote]
回复 点赞
如影随从 2011年08月01日
第一项
第二项
因为i++是先赋值再去++的,而++i是先++再赋值的,所以数据在输出的时候,先是str[0],再是str[1].
回复 点赞
jilonglv 2011年08月01日
有了 经8楼 提示,那个 就用 压栈 顺序和 ++ 操作符来解释就行了。。。。。。
回复 点赞
至善者善之敌 2011年08月01日
所以,这个如上所述,看具体编译器入栈的顺序了,没啥好讨论的了
楼主可以结贴了
回复 点赞
至善者善之敌 2011年08月01日
看汇编代码

int i = 0;
004115A2 mov dword ptr [ebp-28h],0
int b = P(str[i++]) + P(str[i++]);
004115A9 mov eax,dword ptr [ebp-28h]
004115AC imul eax,eax,0Ah
004115AF lea ecx,[ebp+eax-1Ch]
004115B3 mov dword ptr [ebp-0FCh],ecx
004115B9 mov edx,dword ptr [ebp-28h]
004115BC add edx,1
004115BF mov dword ptr [ebp-28h],edx
004115C2 mov eax,dword ptr [ebp-28h]
004115C5 imul eax,eax,0Ah
004115C8 lea ecx,[ebp+eax-1Ch]
004115CC mov dword ptr [ebp-100h],ecx
004115D2 mov edx,dword ptr [ebp-28h]
004115D5 add edx,1
004115D8 mov dword ptr [ebp-28h],edx
004115DB mov eax,dword ptr [ebp-100h] //重点是这里把第二次操作的数据先压栈
004115E1 push eax //看压栈顺序
004115E2 call P (41112Ch)
004115E7 add esp,4
004115EA mov esi,eax
004115EC mov ecx,dword ptr [ebp-0FCh] //把第一次操作数据压栈
004115F2 push ecx //看压栈顺序
004115F3 call P (41112Ch)
004115F8 add esp,4
004115FB add eax,esi
004115FD mov dword ptr [ebp-34h],eax
return 0;
回复 点赞
superliu1122 2011年08月01日
Debug和Release不一样是因为优化?
回复 点赞
superliu1122 2011年08月01日
VC2005、2008、2010 Debug:

第二项
第一项

VC2005、2008、2010 Release:

第一项
第一项

VC6 Debug:
第一项
第二项

VC6 Release:
第二项
第一项

MingW32
第一项
第二项
回复 点赞
懒得打字 2011年08月01日
这个问题很纠结,不过只需要展开就行了
int b = operator+(P(str[i++]), P(str[i++]));
无论从左到右压栈还是从右到左压栈输出都一样

不过大部分应该都是从右到左压栈
回复 点赞
至善者善之敌 2011年08月01日
实时证明我这边是
第二项
第一项

VS2005
回复 点赞
jilonglv 2011年08月01日
这个和

int i = 0;
cout << i++ << i++ <<endl;

类似的结果,我以为 结合 函数传参顺序 和 ++ 操作符的性质 可以解释上面的问题。
但遇到楼主上的问题 我真的没法解释 这个原理了。。。。。。。。待高手。。。。。
回复 点赞
hongwenjun 2011年08月01日
听听编译器他怎么说的

D:\myapp\11\main.cpp|13|warning: operation on 'i' may be undefined|
D:\myapp\11\main.cpp|13|warning: unused variable 'b'|

回复 点赞
hai040 2011年08月01日
可能是两个第二项
看编译器
回复 点赞
G_8519 2011年08月01日
第一项
第二项

不管是哪个 P(str[i++]) 先执行都是先输出 str[0]
回复 点赞
freetstar 2011年08月01日
分别输出第一项和第二项吧
回复 点赞
hua_yang 2011年08月01日
不同编译器,输出结果是不一样
回复 点赞
发动态
发帖子
C++ 语言
创建于2007-09-28

3.1w+

社区成员

24.8w+

社区内容

C++ 语言相关问题讨论,技术干货分享
社区公告
暂无公告