当前位置: 代码迷 >> C语言 >> 关于++运算符的问题
  详细解决方案

关于++运算符的问题

热度:370   发布时间:2008-06-22 10:52:12.0
关于++运算符的问题
int add(int a,int b)
{
    return (a+b);
}

int a=5;

add(a++,a) =10
add(a,a++) =11
add(++a,a) =12
add(a,++a) =12
add(++a,++a) =14
add(++a,a++) =12
add(a++,a++) =11
add(a++,++a) =13

为什么add(++a,++a) =14,而add(a++,++a) =13呢,现在弄糊涂了,哪位大侠给解释一下吧,万分感谢!
搜索更多相关的解决方案: 运算符  

----------------解决方案--------------------------------------------------------
add(++a,++a) =14
add(++a,a++) =12
add(a++,a++) =11
add(a++,++a) =13
这四个,没意义。

add(a++,a) =10
add(a,a++) =11
add(++a,a) =12
add(a,++a) =12
这四个,我只能告诉你,cdecl调用约定,参数是自右向左入栈的,不过这个不是语言的内容,也并不被保证。

总结:此问题毫无意义,如果是个人好奇想了解,可以在学习汇编以后看编译器生成的汇编代码。
----------------解决方案--------------------------------------------------------
.file    "noname1.c"
    .text
.globl _add
    .def    _add;    .scl    2;    .type    32;    .endef
_add:
    pushl    %ebp
    movl    %esp, %ebp
    movl    12(%ebp), %eax
    addl    8(%ebp), %eax
    popl    %ebp
    ret
    .def    ___main;    .scl    2;    .type    32;    .endef
.globl _main
    .def    _main;    .scl    2;    .type    32;    .endef
_main:
    pushl    %ebp
    movl    %esp, %ebp
    subl    $24, %esp
    andl    $-16, %esp
    movl    $0, %eax
    addl    $15, %eax
    addl    $15, %eax
    shrl    $4, %eax
    sall    $4, %eax
    movl    %eax, -8(%ebp)
    movl    -8(%ebp), %eax
    call    __alloca
    call    ___main
    movl    $5, -4(%ebp)
    movl    -4(%ebp), %eax
    movl    %eax, 4(%esp)
    movl    -4(%ebp), %eax
    movl    %eax, (%esp)
    leal    -4(%ebp), %eax
    incl    (%eax)
    call    _add
    movl    -4(%ebp), %eax
    movl    %eax, 4(%esp)
    leal    -4(%ebp), %eax
    incl    (%eax)
    movl    -4(%ebp), %eax
    movl    %eax, (%esp)
    call    _add
    movl    -4(%ebp), %eax
    movl    %eax, 4(%esp)
    leal    -4(%ebp), %eax
    incl    (%eax)
    movl    -4(%ebp), %eax
    movl    %eax, (%esp)
    call    _add
    leal    -4(%ebp), %eax
    incl    (%eax)
    movl    -4(%ebp), %eax
    movl    %eax, 4(%esp)
    movl    -4(%ebp), %eax
    movl    %eax, (%esp)
    call    _add
    leal    -4(%ebp), %eax
    incl    (%eax)
    movl    -4(%ebp), %eax
    movl    %eax, 4(%esp)
    leal    -4(%ebp), %eax
    incl    (%eax)
    movl    -4(%ebp), %eax
    movl    %eax, (%esp)
    call    _add
    movl    -4(%ebp), %eax
    movl    %eax, 4(%esp)
    leal    -4(%ebp), %eax
    incl    (%eax)
    leal    -4(%ebp), %eax
    incl    (%eax)
    movl    -4(%ebp), %eax
    movl    %eax, (%esp)
    call    _add
    movl    -4(%ebp), %eax
    movl    %eax, 4(%esp)
    leal    -4(%ebp), %eax
    incl    (%eax)
    movl    -4(%ebp), %eax
    movl    %eax, (%esp)
    leal    -4(%ebp), %eax
    incl    (%eax)
    call    _add
    leal    -4(%ebp), %eax
    incl    (%eax)
    movl    -4(%ebp), %eax
    movl    %eax, 4(%esp)
    movl    -4(%ebp), %eax
    movl    %eax, (%esp)
    leal    -4(%ebp), %eax
    incl    (%eax)
    call    _add
    movl    $0, %eax
    leave
    ret
----------------解决方案--------------------------------------------------------
很好,又见GCC
上次给某个人解释汇编,结果连个谢谢都不说
这次不上当了,你自己看吧
----------------解决方案--------------------------------------------------------
麻烦能不能发优化过的代码- -这种代码很难看的好不好- -
----------------解决方案--------------------------------------------------------
又一个未定义行为.. - -
----------------解决方案--------------------------------------------------------
看一下add(++a,a) =12
a(5)先进栈,然后++a(6)再进栈,函数的参数是值拷贝的,也就是说参数6和5被传入函数,函数在堆栈中创建临时变量存放这两个值。所以我认为返回值应该是11啊,为什么编译器返回的是12呢?

请教starwing83!
----------------解决方案--------------------------------------------------------
回复 4# StarWing83 的帖子
感谢starwing83,呵呵
----------------解决方案--------------------------------------------------------
= =下次不说了……
其实前自加应该在函数调用前完成,至于什么时候完成,标准没有规定,所以上面的行为未定义啦,你非要追究的话,其实是这样的:
++a;
add(a,a);
所以是12.
----------------解决方案--------------------------------------------------------
差不多明白了,谢谢啊。后自加就没有这个问题了
----------------解决方案--------------------------------------------------------
  相关解决方案