++i 与 i++ 四种层次认知

来源:互联网 发布:linux修改vim配置 编辑:程序博客网 时间:2024/05/16 12:49

起因:

     上周碰到一同事与我基友探讨i++与++i效率问题。 一个坚持++i效率高于i++,一个确实不明白但坚持二者效率不重要。

     其实这个效率本就可以忽虐不计。 正好当初学C++的时候算是深入研究过。当初还总结了一条自认为仞然正确的结论

    进步的表现就是不断推翻甚至颠覆自己以往深思熟虑过的结论(不同境界就有不同的认知)

    不过对于这个i++, ++i 只能装装用用吧。


1。执行先后顺序, n值大小问题

i = 0; n = i++ 与 n = ++i ; n 值大小的区别, 我觉得这个到没什么好说的, 丝毫没有新意。

2. c++ 中 前置 ++ 与 后置++的操作符的实现(当然是为了与内置类型保持一直的实现 )

++i 返回的是引用, i++返回的是旧值

//前置操作Clazz& Clazz::operator++(){        //will evaluate something        return *this;}//后置操作 Clazz Clazz::operator++(int){        Clazz origin = new Clazz(*this);        ++*this;        return origin;}


3. 由第二个结论, 可以解释一种现象,++++clazz 能够执行 而 clazz++++确不能编译通过。

因为++clazz 返回的是引用, clazz++返回的是旧值.

当然对于内置类型就不一样了, 这两种方式在gcc 下都不能编译通过。

[root@jjy ~/q/exercise/c]# cat plusplusplusi.c#include<stdio.h>void main(){int i = 0;++++i;printf("i++ == %d",i);}[root@jjy ~/q/exercise/c]# gcc plusplusplusi.cplusplusplusi.c: 在函数‘main’中:plusplusplusi.c:4:2: 错误:自增操作数必须是左值  ++++i;  ^#include<stdio.h>void main(){    int i = 0;    i++++;    printf("i++ == %d",i);}[root@jjy ~/q/exercise/c]# gcc iplusplus.ciplusplus.c: 在函数‘main’中:iplusplus.c:4:5: 错误:自增操作数必须是左值  i++++;     ^ 

4. 由第二个结论还经常推论出第四个错误的结论,前缀++ 的效率优于后置++的效率

对于自定义类型, 前置++确实优于后置++,毕竟后置++调用了前置++,这倒没什么好说的。

但是对与内置类型, 比如int,其实效率是没有什么差距的


iplus.c与plusi.c文件

[root@jjy ~/q/exercise/c/test_iplusplius]# cat *.c#include<stdio.h>void main(){int i = 0;i++;printf("i++ == %d",i);}#include<stdio.h>void main(){int i = 0;++i;printf("++i = %d",i);}

效率测试过程,gcc -S 将源文件转化为汇编代码, 查看那二者汇编代码是否一直。

[root@jjy ~/q/exercise/c/test_iplusplius]# cat plusi.s.file"plusi.c".section.rodata.LC0:.string"++i = %d".text.globlmain.typemain, @functionmain:.LFB0:.cfi_startprocpushq%rbp.cfi_def_cfa_offset 16.cfi_offset 6, -16movq%rsp, %rbp.cfi_def_cfa_register 6subq$16, %rspmovl$0, -4(%rbp)addl$1, -4(%rbp)movl-4(%rbp), %eaxmovl%eax, %esimovl$.LC0, %edimovl$0, %eaxcallprintfleave.cfi_def_cfa 7, 8ret.cfi_endproc.LFE0:.sizemain, .-main.ident"GCC: (GNU) 4.8.2".section.note.GNU-stack,"",@progbits[root@jjy ~/q/exercise/c/test_iplusplius]# cat iplus.s     .file    "iplus.c"    .section    .rodata.LC0:    .string    "i++ == %d"    .text    .globl    main    .type    main, @functionmain:.LFB0:    .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    $0, -4(%rbp)    addl    $1, -4(%rbp)    movl    -4(%rbp), %eax    movl    %eax, %esi    movl    $.LC0, %edi    movl    $0, %eax    call    printf    leave    .cfi_def_cfa 7, 8    ret    .cfi_endproc.LFE0:    .size    main, .-main    .ident    "GCC: (GNU) 4.8.2"    .section    .note.GNU-stack,"",@progbits<pre name="code" class="cpp">[root@jjy ~/q/exercise/c/test_iplusplius]# gcc -S iplus.c[root@jjy ~/q/exercise/c/test_iplusplius]# gcc -S plusi.c[root@jjy ~/q/exercise/c/test_iplusplius]# diff iplus.s plusi.s 1c1< .file"iplus.c"---> .file"plusi.c"4c4< .string"i++ == %d"---> .string"++i = %d"

二者汇编码一直, 所以, 第四个结论应该是, 

对于自定义类型, 前置++确实优于后置++,但是对与内置类型,二者没有什么差距(已在VC中验证)


其它相关:

对于  i = 0,  i  = i++ ; printf("%d", i) 这类问题本文不做讨论。

0 0
原创粉丝点击