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

起因:

     上周碰到一同事与我基友探讨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.c
plusplusplusi.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.c
iplusplus.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
	.globl	main
	.type	main, @function
main:
.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


[root@jjy ~/q/exercise/c/test_iplusplius]# cat iplus.s 
    .file    "iplus.c"
    .section    .rodata
.LC0:
    .string    "i++ == %d"
    .text
    .globl    main
    .type    main, @function
main:
.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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值