鱼C论坛

 找回密码
 立即注册
查看: 5273|回复: 14

C++ 同一条程序 怎么结果差这么多

[复制链接]
发表于 2013-7-10 11:23:41 | 显示全部楼层 |阅读模式
1鱼币
#include <iostream>
using std::cout;
using std::endl;

int main()
{
        int j=5,q=0;

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

        cout << "q= "<< q <<"j="<<j<< endl;
        return 0;
}


用VC 6.0   的结果是 q=22;
用vs2010    的结果是 q=24;

最佳答案

查看完整内容

学习C语言,一般来说都是以C90或C99标准为基础来学习的。也就是说,我们要“相信”标准里说的,如果严格按照标准做就不会出问题。你的这个问题,用C标准的话说就是,将产生“未定义的行为”。并且,你用了两种不同的编译器证实了标准里的这一说法。 还有一种学习C语言的方法,就是透过标准,研究某个编译器的底层实现。这个就如前面有人将这段代码基于某个特定的编译器汇编成汇编语言,站在汇编层面看看该编译器是 ...
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2013-7-10 11:23:42 | 显示全部楼层
       学习C语言,一般来说都是以C90或C99标准为基础来学习的。也就是说,我们要“相信”标准里说的,如果严格按照标准做就不会出问题。你的这个问题,用C标准的话说就是,将产生“未定义的行为”。并且,你用了两种不同的编译器证实了标准里的这一说法。
       还有一种学习C语言的方法,就是透过标准,研究某个编译器的底层实现。这个就如前面有人将这段代码基于某个特定的编译器汇编成汇编语言,站在汇编层面看看该编译器是如何实现这些代码的。但是这种做法的坏处是不同编译器有不同的处理方式;好处是,很多C标准中规定的“未定义的行为”都可以被很好的理解并加以利用(很多病毒都要基于这种类型的研究)。
       究竟要用那种方法学C语言,取决于你到底想干什么。如果仅仅把C语言当作一个工具,来实现自己的其它目的,其实遵守C标准就是了。达成目的是关键,没有必要特地去深入研究C语言这种工具。用C语言实在搞不定,换种语言也就是了。我相信大多数人(也就是程序员)都应该抱着这样的态度来学C语言。
      如果你非要把C语言的所有问题专研透,成为一个C语言专家,也很好。不过要知道,社会上对C语言专家的需求良很少,所以竞争就很激烈。并且我个人认为C语言专家对社会的贡献远远比不上程序员。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2013-7-10 11:24:45 | 显示全部楼层
vc6.0  
  mov         eax,dword ptr [ebp-4]
                        5
add         eax,1
              5+1
mov         dword ptr [ebp-4],eax
               6
mov         ecx,dword ptr [ebp-4]
             6
add         ecx,1
              6+1
mov         dword ptr [ebp-4],ecx
                7
mov         edx,dword ptr [ebp-4]
             7
add         edx,dword ptr [ebp-4]
         edx=    7    +   7
mov         eax,dword ptr [ebp-4]
                dword ptr [ebp-4]=7
add         eax,1
           eax=   7+1
mov         dword ptr [ebp-4],eax
            dword ptr [ebp-4]= 8
add         edx,dword ptr [ebp-4]
             edx=14+ 8         
mov         dword ptr [ebp-8],edx
            dword ptr [ebp-8]=         22
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2013-7-10 11:25:51 | 显示全部楼层
vs 2010
0041417C  mov         eax,dword ptr [j]  
                       5
0041417F  add         eax,1  
5+1
00414182  mov         dword ptr [j],eax  
                         6
00414185  mov         ecx,dword ptr [j]  
                       6
00414188  add         ecx,1  
                       6+1
0041418B  mov         dword ptr [j],ecx  
                           7                           
0041418E  mov         edx,dword ptr [j]  
                       7
00414191  add         edx,1  
7+1
00414194  mov         dword ptr [j],edx  
                                8     
00414197  mov         eax,dword ptr [j]  
                        8
0041419A  add         eax,dword ptr [j]  
                      8+8
0041419D  add         eax,dword ptr [j]  
                       16+8
004141A0  mov         dword ptr [q],eax  
                                     24
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2013-7-10 11:59:56 | 显示全部楼层
本帖最后由 格式天下 于 2013-7-10 12:01 编辑

根据你给的反汇编,      VC6 就是 q = (++j) + (++j) + (++j), 这里有三个 ++j ,而VC6先执行前两个++j,这时存放j 这个值的存储区[ebp - 4] 的值为 7 ,然后计算机直接将前两个++J 相加,也就是 (++j) + (++j) , 将[ebp -4 ] 更新为 14 , 然后 再执行后面的 ++j ,最后就是 14+8啦
       而VS2010采用的方法就是将所有的++j先执行一遍啦,也就是讲[j]  这个存储区更新为8后统一执行
8+8+8   
       个人认为VS2010正规一点,但是这种东西一般随编译器不同结果也就不同了,So , 楼主不要那么纠结啦 ^_^

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2013-7-10 12:00:58 | 显示全部楼层
因为那是未定义行为
C明令禁止的 写法
错误的 代码
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2013-7-10 12:06:02 | 显示全部楼层
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2013-7-10 12:16:16 | 显示全部楼层
骗子死全家 发表于 2013-7-10 12:06
给我看看 规定哪一条  还真不知道

C99
J2 Undefined behavior 里面的
  -Between two sequence points, an object is modified more than once, or is modified
and the prior value is read other than to determine the value to be stored

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2013-7-10 12:22:52 | 显示全部楼层
我是师兄 发表于 2013-7-10 12:16
C99
J2 Undefined behavior 里面的
  -Between two sequence points, an object is modified more tha ...

不懂
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2013-7-11 09:28:28 | 显示全部楼层
VC6.0又不支持C99 有什么用?     而且VS系列的也是不完全支持C99的~~
这应该是和编译器的问题有关~~~因为它可能会帮你优化一些代码~~~
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2013-7-11 11:55:41 | 显示全部楼层
zer0 发表于 2013-7-11 09:28
VC6.0又不支持C99 有什么用?     而且VS系列的也是不完全支持C99的~~
这应该是和编译器的问题有关~~~因为它 ...

不仅仅是C99中有这个说法
C++的标准
C89 等等
一样 i+++i++是未定义行为
不是优化的问题
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2013-7-11 15:19:47 | 显示全部楼层
我是师兄 发表于 2013-7-11 11:55
不仅仅是C99中有这个说法
C++的标准
C89 等等

学习了~~~
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2013-7-11 15:19:52 | 显示全部楼层
仰望天上的光 发表于 2013-7-11 12:10
学习C语言,一般来说都是以C90或C99标准为基础来学习的。也就是说,我们要“相信”标准里说的,如果 ...

学习了~~~
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2013-7-11 16:25:21 | 显示全部楼层
来学习一下,以前也一直不懂
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-7-19 13:20

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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