LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
12
返回列表 发新帖
楼主: cxh_nuaa_2001

++i和i++

[复制链接]
 楼主| 发表于 2004-9-21 10:16:32 | 显示全部楼层
但我昨天写了这么一个程序:
#include <stdio.h>

int main()
{
   int i = 3;
   i += i++;
   printf("i = %d", i);
}

结果输出了
i = 7

请问该怎么解释呢?
 楼主| 发表于 2004-9-21 10:17:49 | 显示全部楼层
上面的程序还少了一句

return 0;
发表于 2004-9-21 10:20:14 | 显示全部楼层
先做i++,这时候,i == 3,
后做i +=;这时候这里的i == 4了
所以4 + 3 = 7
发表于 2004-9-21 10:25:19 | 显示全部楼层
看看这个就什么都明白了
#include <stdio.h>
int main( )
{
        int tmp,i;
        tmp = i++;
        tmp = ++i;
        return 0;
}

gcc翻译成的汇编(添加了说明)
        .file        "test.c"
        .text
.globl main
        .type        main, @function
main:
        pushl        %ebp
        movl        %esp, %ebp
        subl        $8, %esp
        andl        $-16, %esp
        movl        $0, %eax
        subl        %eax, %esp
        第一个操作
        movl        -8(%ebp), %edx //临时保存i
        //i自加1
        leal        -8(%ebp), %eax
        incl        (%eax)
       
        movl        %edx, -4(%ebp) //赋值给tmp
       
        第二个操作
        //i自加1
        leal        -8(%ebp), %eax
        incl        (%eax)
       
        //后赋值
        movl        -8(%ebp), %eax
        movl        %eax, -4(%ebp)
       
        movl        $0, %eax
        leave
        ret
        .size        main, .-main
        .section        .note.GNU-stack,"",@progbits
        .ident        "GCC: (GNU) 3.3.3 20040412 (Red Hat Linux 3.3.3-7)"

速度应该几乎一样,中间都使用了寄存器中转
 楼主| 发表于 2004-9-21 15:25:28 | 显示全部楼层
上面 iDay 兄的解释我不同意。
--------------------------------
先做i++,这时候,i == 3,
后做i +=;这时候这里的i == 4了
所以4 + 3 = 7
--------------------------------
如果依照你的解释,那么
#include <stdio.h>

int main()
{
int i = 3;
i *= i++;
printf("i = %d", i);
return 0;
}
就应该输出
i = 12
但实际上输出的是
i = 10
虽然 ++ 的优先级高,但不是按你想象的那么执行的。
发表于 2004-9-21 17:55:01 | 显示全部楼层
i += i++;
应该是先
i=i+1;

i++
看一下下面的程序的汇编表示就清楚了
int main()
{
        int i = 3;
        i += i++;
        return 0;
}
汇编表示
        .file        "test3.c"
        .text
.globl main
        .type        main, @function
main:
        pushl        %ebp
        movl        %esp, %ebp
        subl        $8, %esp //为变量i分配内存
        andl        $-16, %esp
        movl        $0, %eax
        subl        %eax, %esp
        //执行i=3的赋值
        movl        $3, -4(%ebp)
        //下面三个指令执行 i=i+1
        movl        -4(%ebp), %edx
        leal        -4(%ebp), %eax
        addl        %edx, (%eax)
       
        //下面三个指令执行i++
        leal        -4(%ebp), %eax
        incl        (%eax)
        movl        $0, %eax
       
        leave
        ret
        .size        main, .-main
        .section        .note.GNU-stack,"",@progbits
        .ident        "GCC: (GNU) 3.3.3 20040412 (Red Hat Linux 3.3.3-7)"
 楼主| 发表于 2004-9-22 15:23:00 | 显示全部楼层
谢谢上面 zbw76 兄的解释。
这么说,i++没有保存临时的对象了。
发表于 2004-9-22 19:10:18 | 显示全部楼层
没有在堆栈内分配内存,只是临时放在寄存器内。
发表于 2004-9-28 13:15:22 | 显示全部楼层
这样理解正确吗?
当i=3时 i+=i++
先用i做i+=i操作 即i=i+i --> i=3+3=6
再i自增1 即i=6+1

当i=3时 i*=i++
先用i做i*=i操作 即i=i*i --> i=3x3=9
再i自增1 即i=9+1
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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