none
VC产生奇怪的结果,请问是编译器有问题还是我算错了?(就2行代码) RRS feed

答案

  • 你好,这个题还是比较迷惑人的。

    咱们把第二个表达式,拆开来看看,你会发现没那么复杂。

    他的运行顺序应该是这样,咱们运行一次,简化一次表达式

    1 oldExp: (++*++p) * (++*p++);

       exec:   p=p+1;

       *p: 2

       Exp: (++*p)*(++*p++);

    2 oldExp: (++*p) * (++*p++);

       exec:  *p = *p + 1;

      *p : 3

       Exp: (*p)*(++*p++);

    3 oldExp: (++*p) * (++*p++);

       exec: *p = *p + 1;

       *p: 4

       ExpSad*p)*(*p);

    4  oldExp: int n = (++*p) * (++*p++);

         exec: n = *p * *p;

        n: 16

    5 oldExp: (++*p) * (++*p++);

       exec: p = p + 1;

       *p: undefined

    无论是 (++*++p) 还是 (++*p++),结果都是返回*p;那么最后就是*p相乘。结果自然是平方。

    其实最简单的

    int m = 1;

    int n = m*++m;

    会发现n是4。

     

    2009年1月9日 13:47
    版主

全部回复

  • 你好,这个题还是比较迷惑人的。

    咱们把第二个表达式,拆开来看看,你会发现没那么复杂。

    他的运行顺序应该是这样,咱们运行一次,简化一次表达式

    1 oldExp: (++*++p) * (++*p++);

       exec:   p=p+1;

       *p: 2

       Exp: (++*p)*(++*p++);

    2 oldExp: (++*p) * (++*p++);

       exec:  *p = *p + 1;

      *p : 3

       Exp: (*p)*(++*p++);

    3 oldExp: (++*p) * (++*p++);

       exec: *p = *p + 1;

       *p: 4

       ExpSad*p)*(*p);

    4  oldExp: int n = (++*p) * (++*p++);

         exec: n = *p * *p;

        n: 16

    5 oldExp: (++*p) * (++*p++);

       exec: p = p + 1;

       *p: undefined

    无论是 (++*++p) 还是 (++*p++),结果都是返回*p;那么最后就是*p相乘。结果自然是平方。

    其实最简单的

    int m = 1;

    int n = m*++m;

    会发现n是4。

     

    2009年1月9日 13:47
    版主
  • 由此我想起了另一个问题,以前有个朋友问我这个运行的结果。

    Code Snippet

    int m = 1;

    m = m++;

     

     

    // What is m value

    我认为这个m应该是1;

    m++;

    相当于

    Code Snippet

        const int operator++(int)

        {

            int temp = m;

            m++;

            return temp;

        }

     

     

       读过EffectiveC++的朋友都应该知道上面的运算符重载。这也就是为什么后置++比前置慢的原因。

        那么m=m++;

        最后就是

        m = temp;

       所以m 先被加一,后来又被复原会m。

    但是在VC6中运行,发现结果是2;

    看汇编后发现。

    m 先被m附值,然后被加一。

    Code Snippet
    0040D4BD   mov         eax,dword ptr [ebp-14h]
    0040D4C0   mov         dword ptr [ebp-14h],eax
    0040D4C3   mov         ecx,dword ptr [ebp-14h]
    0040D4C6   add         ecx,1
    0040D4C9   mov         dword ptr [ebp-14h],ecx

     

    但是我在其他的编译器运行的结果却是零。这一点还是值得注意的。


    2009年1月9日 14:00
    版主
  •  

    这是 编译器 和 你的想法不一样……

     

    就是 P++  和  ++P 出现在一个语句中...(找个Java 编译器试试,应该就是12吧)

     

    C++ 最好 不要写这么晦涩的代码……

    2009年1月9日 14:50
  • 这种不标准的代码执行的结果是听天由命的。
    2009年1月9日 17:30
    版主
  •  chenhong_799 写:

    int a[2] = {1, 2}, *p=a;
    int n = (++*++p) * (++*p++);

    为什么n等于16,而不是我期望的结果12

     

     

    如果一个表达式出现多次带副作用的操作符,运算是undefined。

    不过还是会有很多对这种表达式分析的“头头是道”的文章或是书本,hoho

    2009年1月10日 6:53
  • 建议不要依靠编程语言自身的优先级来决定代码执行顺序,可以用括号来划分代码执行的逻辑顺序。

     

    2009年1月12日 2:50
    版主
  • Sheng Jiang 和vbvan说的是对的,既不是你的错又不是编译器的错,是因为这个行为标准没有定义:)

     

    2009年1月12日 3:29
    版主