C++小白问个自增自减的问题
dr.lc2012/08/07软件综合 IP:陕西
#include <iostream.h>
void main()
{
int a,b;
a=3;
b=(a++)+(++a)+(a++);
cout << b << endl;
cout << a << endl;
}

输出了12  6
可是……我怎么觉得应该是13 6呢?
求个详解……谢了 未命名.jpg
未命名1.jpg
来自:计算机科学 / 软件综合
55
已屏蔽 原因:{{ notice.reason }}已屏蔽
{{notice.noticeContent}}
~~空空如也
dr.lc 作者
12年5个月前 IP:未同步
434939
验证了一下各项的值 DSC03444.jpg
未命名.jpg
未命名1.jpg
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
pl_014
12年5个月前 IP:未同步
434940
这种表达式就不必太纠结了,一般来讲,不赞成使用这种表达式,因为这种表达式对于不同的编译器,其结果可能都不同,《C和指针》的第84页给出了一个“非法表达式”在不同编译器下的结果,而且这种表达式更难懂,更难维护,更难移植,更易出错。再有,一般情况下最好用int main而不是void main,void main已经被最新标准完全抛弃掉了。
至于表达式的结果,应该注意一下程序先执行哪条语句,以及这些表达式会返回什么值,这个是关键。
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
dr.lc作者
12年5个月前 IP:未同步
434941
第一个(a++)等于3,这个我能理解
第二个(++a)等于5,这个我也能理解
但是……第三个(a++)等于4,这个是什么原理啊?
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
dr.lc作者
12年5个月前 IP:未同步
434942
回 2楼(pl_014) 的帖子
我表示我还在学习中……问一下……像这种东西有什么用啊?
要换成别的表达式,怎么搞呢?
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
pl_014
12年5个月前 IP:未同步
434952
回 4楼(john667096) 的帖子
你是说像b=(a++)+(++a)+(a++);这种表达式吗?我觉得理解好这个顶多也就能在二级笔试这样的考试和一些脑子有问题的领倒和老师等等上管用。要是我,直接忽略之。
不必纠结怎样将这种表达式换成更好的代码,对于新手,只要写出自己想要实现的功能的代码就行。等把基础学完了,可以再看看那些拨高的书,C语言推荐《C专家编程》、《C陷阱与缺陷》、《C和指针》三大本,C++可以看《C++沉思录》等等。
另外,C++的入门书籍最好不要随便去选,因为C和C++在编程思想上截然不同,如果用C的思想去写C++程序,只能会使代码更繁杂,建议看《C++ primer》或《C++ primer plus》
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
dr.lc作者
12年5个月前 IP:未同步
434954
回 5楼(pl_014) 的帖子
看的是C++ primer
还挺不错的……至少能看懂……
解释一下前自增和后自增吧吧……想了好久都不明白……
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
pl_014
12年5个月前 IP:未同步
434961
回 6楼(john667096) 的帖子
哦,a++的返回值是a,执行后a将会增加1,++a的返回值是a+1,执行后a同样会增加1。新手理解到这就没问题了,我对这种东西也是理解到这种程度的。
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
dr.lc作者
12年5个月前 IP:未同步
434966
回 7楼(pl_014) 的帖子
就是说:
经过k=a++运算之后,输出的k=原来的a,a=原来的a+1
经过k=++a运算之后,输出的k=原来的a+1,a=原来的a+1
对吧……

那这么说的话……我原来觉得应该输出13 6 是对的!
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
phpskycn
12年5个月前 IP:未同步
434990
回 8楼(john667096) 的帖子
编译好反汇编,运算完了下个断点。

a=3;
000D13BE C7 45 F8 03 00 00 00 mov         dword ptr [a],3  
b=(a++)+(++a)+(a++);
000D13C5 8B 45 F8             mov         eax,dword ptr [a]  
000D13C8 83 C0 01             add         eax,1  
000D13CB 89 45 F8             mov         dword ptr [a],eax  
000D13CE 8B 4D F8             mov         ecx,dword ptr [a]  
000D13D1 03 4D F8             add         ecx,dword ptr [a]  
000D13D4 03 4D F8             add         ecx,dword ptr [a]  
000D13D7 89 4D EC             mov         dword ptr [b],ecx  
000D13DA 8B 55 F8             mov         edx,dword ptr [a]  
000D13DD 83 C2 01             add         edx,1  
000D13E0 89 55 F8             mov         dword ptr [a],edx  
000D13E3 8B 45 F8             mov         eax,dword ptr [a]  
000D13E6 83 C0 01             add         eax,1  
000D13E9 89 45 F8             mov         dword ptr [a],eax  

可以看到,首先给a赋值为3。
随后送进寄存器+1再送回来
然后:传给ecx,并两次加上自己,最后赋值给b(相当于b = a*3),最后又用老办法给a+1两次
最后b = (a+1)*3  =12
a = a+1+1+1 = 6
//===================================================================================
同时可以看到,这样效率低下。
a+1可以直接inc DWord ptr[a]
而不是送进寄存器加完再送出来
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
dr.lc作者
12年5个月前 IP:未同步
434991
回 9楼(phpskycn) 的帖子
so……这么说的话……a++和++a没有区别啊……
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
pl_014
12年5个月前 IP:未同步
434999
回 8楼(john667096) 的帖子
对,至于那个表达式就不清楚了。
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
pl_014
12年5个月前 IP:未同步
435000
回 10楼(john667096) 的帖子
两者单独作为一条语句是没有区别的,但是像你刚才的那样作为表达式赋值就不一样了。
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
dr.lc作者
12年5个月前 IP:未同步
435009
回 12楼(pl_014) 的帖子
了然……了然……
多谢了!
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
pl_014
12年5个月前 IP:未同步
435011
我也贴出来我的g++编译器的具体情况吧,代码我稍作了改动,如下
#include <iostream>
int main()
{
int a,b;
a=3;
b=(a++)+(++a)+(a++);
std::cout << b << std::endl;
std::cout << a << std::endl;
return 0;
}

g++生成的对应汇编代码(AT&T格式)
    .file    "XXXXXXXXXXXXXXX"
    .local    _ZStL8__ioinit
    .comm    _ZStL8__ioinit,1,1
    .text
    .globl    main
    .type    main, @function
main:
.LFB969:
    .cfi_startproc
    pushq    %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register 6
    subq    $16, %rsp
    movl    $3, -4(%rbp)
    addl    $1, -4(%rbp)
    movl    -4(%rbp), %eax
    leal    (%rax,%rax), %edx
    movl    -4(%rbp), %eax
    addl    %edx, %eax
    movl    %eax, -8(%rbp)
    addl    $1, -4(%rbp)
    addl    $1, -4(%rbp)
    movl    -8(%rbp), %eax
    movl    %eax, %esi
    movl    $_ZSt4cout, %edi
    call    _ZNSolsEi
    movl    $_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_, %esi
    movq    %rax, %rdi
    call    _ZNSolsEPFRSoS_E
    movl    -4(%rbp), %eax
    movl    %eax, %esi
    movl    $_ZSt4cout, %edi
    call    _ZNSolsEi
    movl    $_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_, %esi
    movq    %rax, %rdi
    call    _ZNSolsEPFRSoS_E
    movl    $0, %eax
    leave
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE969:
    .size    main, .-main
    .type    _Z41__static_initialization_and_destruction_0ii, @function
_Z41__static_initialization_and_destruction_0ii:
.LFB975:
    .cfi_startproc
    pushq    %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register 6
    subq    $16, %rsp
    movl    %edi, -4(%rbp)
    movl    %esi, -8(%rbp)
    cmpl    $1, -4(%rbp)
    jne    .L3
    cmpl    $65535, -8(%rbp)
    jne    .L3
    movl    $_ZStL8__ioinit, %edi
    call    _ZNSt8ios_base4InitC1Ev
    movl    $__dso_handle, %edx
    movl    $_ZStL8__ioinit, %esi
    movl    $_ZNSt8ios_base4InitD1Ev, %edi
    call    __cxa_atexit
.L3:
    leave
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE975:
    .size    _Z41__static_initialization_and_destruction_0ii, .-_Z41__static_initialization_and_destruction_0ii
    .type    _GLOBAL__sub_I_main, @function
_GLOBAL__sub_I_main:
.LFB976:
    .cfi_startproc
    pushq    %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register 6
    movl    $65535, %esi
    movl    $1, %edi
    call    _Z41__static_initialization_and_destruction_0ii
    popq    %rbp
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE976:
    .size    _GLOBAL__sub_I_main, .-_GLOBAL__sub_I_main
    .section    .init_array,"aw"
    .align 8
    .quad    _GLOBAL__sub_I_main
    .hidden    __dso_handle
    .ident    "GCC: (Debian 4.7.1-2) 4.7.1"
    .section    .XXXXXXXU-stack,"",@progbits

编译时的警告,可见这种用法是不推荐的

程序执行后的结果
12
6
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
dr.lc作者
12年5个月前 IP:未同步
435013
回 14楼(pl_014) 的帖子
完全看不懂这个代码……
求人类语言解释……
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
pl_014
12年5个月前 IP:未同步
435014
再水一贴,发现楼主的cout和endl前既没加上std::,也没有前面加using namespace std,这种用法在标准C++是不允许的,也许你用的编译器能容纳这样的错误,但总的来说,最好不要这样做,本人推荐用std::cout、std::endl这种形式。
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
pl_014
12年5个月前 IP:未同步
435020
回 15楼(john667096) 的帖子
哦哦,看不懂就算了,其实我也不怎么懂,拿出来仅供参考。
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
acmilan
12年5个月前 IP:未同步
435026
C#代码
using System;

class NaRsf
{
    static void Main()
    {
        int a=3;
        int b=(a++)+(++a)+(a++);
        Console.WriteLine(b);
        Console.WriteLine(a);
    }
}
输出13,6
C#语言是编译成字节码,通过.NET的CLR运行的,而C++则是编译成机器指令运行的
机器指令有乱序执行引擎,而.NET的CLR没有
看来可能是计算机的乱序执行引擎捣的鬼
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
dr.lc作者
12年5个月前 IP:未同步
435027
回 17楼(pl_014) 的帖子
其实……我只是为了打发暑假的无聊时光……才学C++的……
一暑假能学成个半吊子,我就很满足了……
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
pl_014
12年5个月前 IP:未同步
435030
回 19楼(john667096) 的帖子
呵呵,真心想学就好,总比那些学了只为应付二级考试的要强得多!
C++的东西比C语言多,不如C语言好学,不过楼主要是对C++感兴趣的话,只学C++也无所谓。
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
acmilan
12年5个月前 IP:未同步
435031
上图,C#运行无误[s:275] plusplusplus.png
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
phpskycn
12年5个月前 IP:未同步
435033
回 21楼(acmilan) 的帖子
根据反汇编结果再翻译回来:
a++;
b = a;
b = b+a;
b = b+a;
a++;
a++;
跟乱序执行没什么关系
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
acmilan
12年5个月前 IP:未同步
435042
perl执行的结果也是13,6
$a=3;
$b=($a++)+(++$a)+($a++)
say $b
say $a[s:275]
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
acmilan
12年5个月前 IP:未同步
435054
看来是我孤陋寡闻了[s:275]任何一个C/C++编译器编译的都是12,6,包括古老的TurboC
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
pl_014
12年5个月前 IP:未同步
435071
回 24楼(acmilan) 的帖子
哦,这样还好,《C和指针》那里举了一个很鲜明的例子,在各种编译器上的结果可以说是千差万别。
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
acmilan
12年5个月前 IP:未同步
435080
这是我编译的代码的运算阶段汇编指令:
运算阶段代码分析

    movl    $3, -8(%rbp)   ; a=3;
    addl    $1, -8(%rbp)   ; a++;
    movl    -8(%rbp), %eax ; eax=a;
    addl    %eax, %eax     ; eax+=eax
    addl    -8(%rbp), %eax ; eax+=a;
    movl    %eax, -4(%rbp) ; b=eax
    addl    $1, -8(%rbp)   ; a++;
    addl    $1, -8(%rbp)   ; a++;

可见是先算中间那个,然后再互相加起来,最后才执行第一个和第三个[s:275]
这个东西括号里是“同步”计算的
相当于:
int a,b;
a=3;
++a;
b=a+a+a;
a++;
a++;
+100
科创币
phpskycn
2012-08-09
正确答案
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
acmilan
12年5个月前 IP:未同步
435095
而一般的解释语言都是异步计算的,即按结合顺序由外向内进行运算,可是C/C++则是同步计算,即按优先级由内向外进行运算
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
phpskycn
12年5个月前 IP:未同步
435099
根据反汇编结果,编译器似乎理解为:
b = (a+1)+(a+1)+(a+1)
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
acmilan
12年5个月前 IP:未同步
435105
回 28楼(phpskycn) 的帖子
正确
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
pl_014
12年5个月前 IP:未同步
435140
回 26楼(acmilan) 的帖子
啊,你会AT&T汇编?看什么教程比较好?
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
acmilan
12年5个月前 IP:未同步
435172
我是看的Professional Assembly Language (Richard Blum),不过那是2005年的版本,还只有32位版

其实AT&T汇编就这几条
1、源optcode和目的optcode完全颠倒,Intel右到左,AT&T左到右,但要注意CMP指令也是完全颠倒
2、指令代号后会有一个“类型说明符”,比如字节为b,字为w,长整型为l,64位整形为q
3、立即数前加$,寄存器前加%,符号表示地址,圆括号为寻址,括号内外相加得实际地址。
4、短跳转用jmp,长跳转用ljmp $section,$offset
5、多看看编译后的xxx.s汇编程序,你就知道怎么用了
6、没有了
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
pl_014
12年5个月前 IP:未同步
435179
回 31楼(acmilan) 的帖子
哦,知道了,谢谢。
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
acmilan
12年5个月前 IP:未同步
435181
亚马逊和当当上只有几本是AT&T的
但新浪爱问、百度文库里有不少
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
acmilan
12年5个月前 IP:未同步
435210
C/C++编译器,推荐和操作系统结合最紧密的winsdk,移植的mingw也行,不推荐使用posix子系统例如cygwin
不要使用过老的编译器,例如VC++6.0,这个是貌似只有国内还在用的老古董。。。
linux下当然gcc/g++
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
phpskycn
12年5个月前 IP:未同步
435211
回 34楼(acmilan) 的帖子
VC6可以摆脱万恶的运行库……
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
okingkoom
12年5个月前 IP:未同步
435227
支持2楼。学习以实用为目标,而不是为了炫耀。在容易出错的地方去炫耀,除了对自己的代码不负责(也许会自以为自己很懂很正确),也是对旁人阅读理解上的不负责。当然为了应付国家等级考试而不得不学,则无奈了。

我记得很早以前有篇文章说,老印的软件业发达;老印的学生写出来的代码一般不是效率最高的,但是基本上所有的学生写同一任务的的代码都差不多;而中国学生则良莠不齐,有些人写错,有些人效率极高且对。现在基本上没有单打独斗的软件开发者,但对软件开发团队来说,规范、可读是最主要的。
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
acmilan
12年5个月前 IP:未同步
435241
回 36楼(okingkoom) 的帖子
谭浩强之类的国内的考试书籍,可以让人养成以下几个坏习惯:
1、不写注释,以为自己懂,别人都懂
2、重复复制粘贴书上的算法代码,而不是编写算法程序库
3、使用落后的开发工具(比如TurboC2.0或VC++6而不是VC++2010或GCC)
4、喜欢卖弄小技巧
5、不思做大程序(谭浩强的C教程通篇讲语言细节,根本就没有工程的章节)
而且在早已过时的平台上用不是为这个平台设计的语言,写一些似乎只在考试里有用的程序,是很让人厌烦的。[s:275]
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
acmilan
12年5个月前 IP:未同步
435250
回 35楼(phpskycn) 的帖子
[s:275]您的windows server 2003r2似乎是不自带.net framework的?
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
eifheowvd
12年5个月前 IP:未同步
435257
回 35楼(phpskycn) 的帖子
同感,目前来说VC6还是不可或缺的
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
acmilan
12年5个月前 IP:未同步
435287
[s:275]由于微软的高端机路线,以后Windows XP的机子也许只能装Win7Starter了……不过这也是一种办法
另一种办法是:我们自己为Windows XP提供技术支持。不过照目前的学术氛围来看,难度挺大。。。
哦我忘了,还有龙芯和RedFlag……[s:178]

闲话少说,现在Qt都支持VC++2010了,而且VC++2010不需要.NET,是非托管代码,还在等什么?[s:230]
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
我说要有光
12年5个月前 IP:未同步
435295
表示坚决不向VC6妥协,偶尔遇到些不规矩的代码改一改又有什么大不了的
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
phpskycn
12年5个月前 IP:未同步
435379
回 38楼(acmilan) 的帖子
不是,net,是万恶的MSVC Runtime library
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
phpskycn
12年5个月前 IP:未同步
435386
回 40楼(acmilan) 的帖子
Windows7对机器的要求不是特别变态啊(相对当年Vista,好很多)。
06年的中端电脑(Core 2 DUO E4300+1GB RAM)完全无压力。
Windows8看起来也还行,32位专业版装好占用内存大约400MB左右。
=======================================================
Windows 7/8 Start也是个不错的选择,功能并没有被限制太多
=======================================================
微软早就想到“淘汰”XP的问题,本来WRK计划放出Windows NT 5.1.2600的内核也被取消,大概就是怕这个吧。
感觉用2003的内核,把server版关掉的那些功能再打开,或许是个不错的选择
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
acmilan
12年5个月前 IP:未同步
435534
回 42楼(phpskycn) 的帖子
写个Hello, World!还是不需要MSVCR100.DLL的[s:274]
nomsvcr.png
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
dr.lc作者
12年5个月前 IP:未同步
435589
不对不对……怎么水得我都跟不上了……
+10
科创币
acmilan
2012-08-09
长知识了
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
雾雨魔理沙
12年5个月前 IP:未同步
436115
呵呵,看了下楼上几位大神的汇编码,看大家热情蛮高就忍不住来凑一下

其实,这个问题不能完全按照执行顺序的思路考虑,
其实连加式子比较蒙人在于编译器有“运算优先级”的问题,前边几位已经说过了。
不妨试一下:
a = 3;
b = a++;
b = ++a + b;
b =  (a++)  + b;
printf("%d\\n %d\\n",b,a);
断点看一下 就明了了

其实个人认为,学编程的话,这些内容相对边缘,不如多了解些实用的知识,
比如记住自加运算在C/C++中,前++效率要略好。
+10
科创币
acmilan
2012-08-09
我也是这么想的,贵在实用,整天搞小技巧干不成大事
+1
科创币
phpskycn
2012-08-09
有道理,可是这样分解算出来的不对……
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
phpskycn
12年5个月前 IP:未同步
436191
回 46楼(雾雨魔理沙) 的帖子
输出结果是13,6……26楼已经正确解答
46楼的代码反汇编……
Microsoft Visual C++ 10.0.30319.1_RTM

a = 3;
00F7354E C7 45 F8 03 00 00 00 mov         dword ptr [a],3  
b = a++;
00F73555 8B 45 F8             mov         eax,dword ptr [a]  
00F73558 89 45 EC             mov         dword ptr [b],eax  
00F7355B 8B 4D F8             mov         ecx,dword ptr [a]  
00F7355E 83 C1 01             add         ecx,1  
00F73561 89 4D F8             mov         dword ptr [a],ecx  
b = ++a + b;
00F73564 8B 45 F8             mov         eax,dword ptr [a]  
00F73567 83 C0 01             add         eax,1  
00F7356A 89 45 F8             mov         dword ptr [a],eax  
00F7356D 8B 4D F8             mov         ecx,dword ptr [a]  
00F73570 03 4D EC             add         ecx,dword ptr [b]  
00F73573 89 4D EC             mov         dword ptr [b],ecx  
b =  (a++)  + b;
00F73576 8B 45 F8             mov         eax,dword ptr [a]  
00F73579 03 45 EC             add         eax,dword ptr [b]  
00F7357C 89 45 EC             mov         dword ptr [b],eax  
00F7357F 8B 4D F8             mov         ecx,dword ptr [a]  
00F73582 83 C1 01             add         ecx,1  
00F73585 89 4D F8             mov         dword ptr [a],ecx
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
雾雨魔理沙
12年5个月前 IP:未同步
436525
回 47楼(phpskycn) 的帖子

我写那段代码 是按从右到左的顺序,单步执行运算过程的,目的是为了前++与后++运算看着更清晰,
不是为了得出连加式子正确结果的…[s:272] 可能是我之前没有阐明。

我认为这个问题涉及的知识点包括:
前++与后++的区别
C/C++ 单行语句执行顺序
C/C++ 执行运算优先级
以上三点,而对于真正开发人员更实用的知识其实是前两条,同时了解效率差异,就够用了 呵呵。
+100
科创币
phpskycn
2012-08-10
right
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
phpskycn
12年5个月前 IP:未同步
436538
请教一下,对于LZ的代码,VC++编译后相当低效,从时间和空间上都不怎么样:

000D13BE C7 45 F8 03 00 00 00 mov         dword ptr [a],3  
000D13C5 8B 45 F8             mov         eax,dword ptr [a]  
000D13C8 83 C0 01             add         eax,1  
000D13CB 89 45 F8             mov         dword ptr [a],eax  
000D13CE 8B 4D F8             mov         ecx,dword ptr [a]  
000D13D1 03 4D F8             add         ecx,dword ptr [a]  
000D13D4 03 4D F8             add         ecx,dword ptr [a]  
000D13D7 89 4D EC             mov         dword ptr [b],ecx  
000D13DA 8B 55 F8             mov         edx,dword ptr [a]  
000D13DD 83 C2 01             add         edx,1  
000D13E0 89 55 F8             mov         dword ptr [a],edx  
000D13E3 8B 45 F8             mov         eax,dword ptr [a]  
000D13E6 83 C0 01             add         eax,1  
000D13E9 89 45 F8             mov         dword ptr [a],eax  

就不说啥智能化,VC++对于递增的处理就有问题,先将变量传入寄存器再递增最后再传回……蛋疼
感觉稍微高效点应该是这样

mov a,3
inc a
mov eax,a
add eax,a
add eax,a
mov b,eax
inc a
inc a

请教有没有让VC自己优化的办法?
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
雾雨魔理沙
12年5个月前 IP:未同步
436630
这…据我所知,编译器将C/C++码转汇编码的法则是固定的,
也就是说,作为编译器的使用者似乎不能干涉到这个层面… 呃…也许是我知道的不够[s:275]

其实以我的了解,查汇编码的目的,更多时候是为了解释为什么相同结果的一段代码,
执行起来效率千差万别,这个时候,看一看C码转汇编码,多数时候就一目了然了。

所以说如果从C/C++这个层面做代码,
我们能做的只有深刻的理解或者铭记一些编程法则,从C/C++代码的层面来提高效率,

就比如
循环嵌套的慎用,if语句的写法,
函数调用原理引入思考C++内联函数的优缺,友元函数的优缺,
地址操作引入思考指针参数传递的好处,创建对象的情况…等等。
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论

想参与大家的讨论?现在就 登录 或者 注册

所属专业
上级专业
同级专业
dr.lc
学者 笔友
文章
95
回复
1623
学术分
1
2012/04/30注册,6年11个月前活动
暂无简介
主体类型:个人
所属领域:无
认证方式:邮箱
IP归属地:未同步
文件下载
加载中...
{{errorInfo}}
{{downloadWarning}}
你在 {{downloadTime}} 下载过当前文件。
文件名称:{{resource.defaultFile.name}}
下载次数:{{resource.hits}}
上传用户:{{uploader.username}}
所需积分:{{costScores}},{{holdScores}}下载当前附件免费{{description}}
积分不足,去充值
文件已丢失

当前账号的附件下载数量限制如下:
时段 个数
{{f.startingTime}}点 - {{f.endTime}}点 {{f.fileCount}}
视频暂不能访问,请登录试试
仅供内部学术交流或培训使用,请先保存到本地。本内容不代表科创观点,未经原作者同意,请勿转载。
音频暂不能访问,请登录试试
支持的图片格式:jpg, jpeg, png
插入公式
评论控制
加载中...
文号:{{pid}}
投诉或举报
加载中...
{{tip}}
请选择违规类型:
{{reason.type}}

空空如也

加载中...
详情
详情
推送到专栏从专栏移除
设为匿名取消匿名
查看作者
回复
只看作者
加入收藏取消收藏
收藏
取消收藏
折叠回复
置顶取消置顶
评学术分
鼓励
设为精选取消精选
管理提醒
编辑
通过审核
评论控制
退修或删除
历史版本
违规记录
投诉或举报
加入黑名单移除黑名单
查看IP
{{format('YYYY/MM/DD HH:mm:ss', toc)}}