《C和C++程序员面试秘笈》——1.4 i++与++i哪个效率更高

简介:

本节书摘来自异步社区出版社《C和C++程序员面试秘笈》一书中的第1章,第1.4节,作者: 董山海,更多章节内容可以访问云栖社区“异步社区”公众号查看。

1.4 i++与++i哪个效率更高

C和C++程序员面试秘笈
考点: i++和++i的效率比较

出现频率:

【解析】

在这里声明,简单地比较前缀自增运算符和后缀自增运算符的效率是片面的,因为存在很多因素影响这个问题的答案。首先考虑内建数据类型的情况:如果自增运算表达式的结果没有被使用,而是仅仅简单地用于增加一员操作数,答案是明确的,前缀法和后缀法没有任何区别,编译器的处理都应该是相同的,很难想象得出有什么编译器实现可以别出心裁地在二者之间制造任何差异。我们看看下面这个程序。

  #include <stdio.h>
  int main()
  {
    int i = 0;
    int x = 0;
    i++;
    ++i;
    x = i++;
    x = ++i;
    return 0;
  }```
上面的代码在VC++ 6.0中编译,得到的汇编如下。

; Line 5
  mov  DWORD PTR _i$[ebp], 0
; Line 6
  mov  DWORD PTR _x$[ebp], 0
; Line 8
  mov  eax, DWORD PTR _i$[ebp]
  add  eax, 1
  mov  DWORD PTR _i$[ebp], eax
; Line 9
  mov  ecx, DWORD PTR _i$[ebp]
  add  ecx, 1
  mov  DWORD PTR _i$[ebp], ecx
; Line 10
  mov  edx, DWORD PTR _i$[ebp]
  mov  DWORD PTR _x$[ebp], edx
  mov  eax, DWORD PTR _i$[ebp]
  add  eax, 1
  mov  DWORD PTR _i$[ebp], eax
; Line 11
  mov  ecx, DWORD PTR _i$[ebp]
  add  ecx, 1
  mov  DWORD PTR _i$[ebp], ecx
  mov  edx, DWORD PTR _i$[ebp]
  mov  DWORD PTR _x$[ebp], edx`
代码段第8行和第9行生成的汇编代码分别对应Line 8和Line 9下对应的汇编代码,可以看到3个步骤几乎完全一样。

代码段第10~11行生成的汇编代码分别对应Line 10和Line 11下对应的汇编代码,可以看到都是5个步骤,只是在加1的先后顺序上有一些区别,效率也是完全一样的。

由此说明,考虑内建数据类型时,它们的效率差别不大(去除编译器优化的影响)。所以在这种情况下,我们大可不必关心。

现在让我们再考虑自定义数据类型(主要是指类)的情况。此时我们不需要再做很多汇编代码的分析了,因为前缀式(++i)可以返回对象的引用,而后缀式(i++)必须返回对象的值,所以导致在大对象的时候产生了较大的复制开销,引起效率降低。因此处理使用者自定义类型(注意不是指内建类型)的时候,应该尽可能地使用前缀式递增/递减,因为它天生“体质”较佳。

【答案】

内建数据类型的情况,效率没有区别。

自定义数据类型的情况,++i效率较高。

相关文章
|
11月前
|
缓存 安全 编译器
C++面试周刊(3):面试不慌,这样回答指针与引用,青铜秒变王者
《C++面试冲刺周刊》第三期聚焦指针与引用的区别,从青铜到王者级别面试回答解析,助你21天系统备战,直击高频考点,提升实战能力,轻松应对大厂C++面试。
941 132
C++面试周刊(3):面试不慌,这样回答指针与引用,青铜秒变王者
|
存储 算法 编译器
C++面试题其一
C++文件编译与执行的四个阶段 预处理:处理#include、#define等预处理指令。 编译:将源码翻译为目标代码。 汇编:将目标代码转换为机器指令。 链接:将目标文件和库文件合并生成可执行文件。 STL中的vector的实现,是怎么扩容的? vector通过动态数组实现,当容量不足时,分配更大的内存(通常是原来的两倍),复制旧数据到新内存,并释放旧内存。
299 2
|
存储 程序员 编译器
C++面试题其二
extern "C" 用于告诉编译器按照C语言的链接方式处理代码,通常用于C++代码与C代码混合编程,以防止因名字修饰(name mangling)引起的链接错误。例如: extern "C" { void c_function(); } 通过这些问题的深入理解和解答,能够更好地掌握C++编程的核心概念和实际应用,为面试做好充分的准备。
273 1
|
存储 网络协议 编译器
【干货总结】Linux C/C++面试知识点
Linux C/C++基础与进阶知识点,不仅用于面试,平时开发也用得上!
1486 124
|
IDE Java 程序员
C++ 程序员的 Java 指南
一个 C++ 程序员自己总结的 Java 学习中应该注意的点。
224 5
|
算法 程序员 Go
PHP 程序员学会了 Go 语言就能唬住面试官吗?
【9月更文挑战第8天】学会Go语言可提升PHP程序员的面试印象,但不足以 solely “唬住” 面试官。学习新语言能展现学习能力、拓宽技术视野,并增加就业机会。然而,实际项目经验、深入理解语言特性和综合能力更为关键。全面展示这些方面才能真正提升面试成功率。
278 10
|
JavaScript 前端开发 小程序
CoderGuide 程序员前后端面试题库,打造全网最高质量题库
CoderGuide涵盖范围包括且不限于:前端面试题(Vue,React,JS,HTTP,HTML,CSS面试题等),后端面试题(Java,Python,Golang,PHP,Linux,Mysql面试题等),以及算法面试题,大厂面试题,高频面试题,校招面试题等,你想要的,这里都有!
480 2
|
前端开发 应用服务中间件 程序员
老程序员分享:Nginx相关面试题
老程序员分享:Nginx相关面试题
332 2
|
SQL JavaScript Java
java程序员面试题大全含答案(2018--2019)
java程序员面试题大全含答案(2018--2019)
|
域名解析 网络协议 程序员
程序员必知:【转】adns解析库——域名解析实例(C++、linux)
程序员必知:【转】adns解析库——域名解析实例(C++、linux)
346 0