从事 C/C++ 编程快8个年头了,今天朋友突然问我:什么时候用 C 而不用 C++?一下子把我的思绪拉入往昔那些使用 C 和 C++ 的“峥嵘岁月”里。朋友还是原来的朋友,而我却不是当初的那个我了。

老实说,这些年用 C 和 C++ 分别写过很多项目,也研究像 Linux 内核、Nginx、Redis、freeswitch 等各种经典 C 项目,当然研究的 C++ 项目也不少(例如 MySQL 的源码),玩的不亦乐乎,常看常新,看到这些经典项目的精彩代码处时有时候喜不自禁,那真是笑看妻子愁何在,漫卷诗书喜欲狂。

贴几张图:

调试分析 C 项目 Redis 源码

调试分析 C 项目 Nginx 源码

调试分析 C++ 项目 MySQL Server 8.0

如果一个项目如果对内存和编译后的机器指令做精准控制,那么应该优先选择 C 而不是 C++,C++ 编译器在背后插入了太多的指令。举两个例子:

class A {
public:A() {}~A() {}
};int main()
{A a;return 0;
}

这个例子说明了在 C++ 中一个对象出了其作用域(这里是 a),会自动调用其析构函数,这是编译器自动加入的:

 A a;
00007FF71E2918DD  lea         rcx,[a]
00007FF71E2918E1  call        A::A (07FF71E291302h)  return 0;
00007FF71E2918E6  mov         dword ptr [rbp+0E4h],0
00007FF71E2918F0  lea         rcx,[a]
00007FF71E2918F4  call        A::~A (07FF71E291258h)  ;编译在这里自动插入调用类A的析构函数
00007FF71E2918F9  mov         eax,dword ptr [rbp+0E4h]
}

再比如假设 A 类有一个实例方法 f,编译器的调用 A 方法的实现是编译器自动插入了一个 this 指针作为方法的第一个参数:

class A {
public:A() {}~A() {}void f(int a, int b) {}
};int main()
{A a;a.f(1, 2);return 0;
}

汇编代码如下:

 A a;
00007FF7157D193D  lea         rcx,[a]
00007FF7157D1941  call        A::A (07FF7157D1311h)
00007FF7157D1946  nop  a.f(1, 2);                       ;由于函数调用方式是__thiscall,
00007FF7157D1947  mov         r8d,2  ;所以参数从右往左入栈,这是第一个参数2
00007FF7157D194D  mov         edx,1  ;这是第一个参数的1
00007FF7157D1952  lea         rcx,[a];这是对象a的地址,即this指针
00007FF7157D1956  call        A::f (07FF7157D110Eh)  ;调用a的方法freturn 0;
00007FF7157D195B  mov         dword ptr [rbp+0E4h],0
00007FF7157D1965  lea         rcx,[a]
00007FF7157D1969  call        A::~A (07FF7157D1267h)
00007FF7157D196E  mov         eax,dword ptr [rbp+0E4h]  

同样的道理,如果一个复杂的 C++ 工程中,一个类有多个复杂类型成员,而这些复杂类型成员又有多个复杂类型成员,这种层级关系比较深的情况下,上层对象的构造函数会自动触发其成员变量的构造函数的调用,而进而又触发下一级成员变量的构造函数的调用,而析构函数正好反过来,这些构造动作都是编译器自己往开发者的程序中插入的指令。如果要涉及到模板或者像智能指针包裹的对象的构造、析构和移动,那编译器自动嵌入的指令就更多。

以上,在 C 编译器中不会有的,C 编译器一般不会偷偷插入开发者不知道的指令,你写了什么代码,对应的机器指令和你预期的所差无几。这就是为什么像内核以及一些对性能和内存利用率要求比较高的项目需要使用 C 而不是 C++。

有同学可能会说,用 C++ 不用 C 的时候,是因为 C++ 支持类、支持面向对象编程,需要用到面向对象特性的时候由于 C++ 带类的功能,确实让我们编写面向对象程序方便一些,但不能作为用 C++ 而不用 C 的主要理由之一。面向对象是一种编程思想,用 C 也可以写出优雅的面向对象程序来。

最后我想说的是,C 和 C++ 学起来是很爽,就是头感觉凉飕飕的,哈哈。。。


今天的分享就到这里了,大家要好好学C语言/C++哟~

欢迎转行和学习编程的伙伴,利用更多的资料学习成长比自己琢磨更快哦!

对于准备学习C/C++编程的小伙伴,如果你想更好的提升你的编程核心能力(内功)不妨从现在开始!

什么时候用 C 而不用 C++?相关推荐

  1. Android Studio 配置OpenCV4.4.0 不用安装OpenCV Manager (泪崩居然用了礼拜天2天的时间居然还没配置成功,今天又看了下配置成功了)

    Android Studio 配置OpenCV4.4.0 ,说来惭愧居然用户礼拜天2天的时间呢,期间遇到的问题大致有4个问题 这里我也总结出了最后在列举出来,(可能是新版和之前旧版本不一样的问题按照网 ...

  2. java new 引用_java不用new运算符也能创建引用吗?

    java不用new运算符也能创建引用吗? 关注:269  答案:6  mip版 解决时间 2021-01-30 06:37 提问者终不敌时光 2021-01-29 19:10 out.currentT ...

  3. 何不用python_EXCEL数据太“脏”无从下手?何须用python,ETL一分钟搞定

    我们日常在处理数据的过程中,总是会遇到各种千奇百怪的数据源,不是这里有重复值,就是那里的数据有缺失,这些"脏数据"不得不花费我们大量的时间去进行清理,让人十分苦恼.造成这些&quo ...

  4. oracle为什么不用指定数据库,两个数据库怎么保持数据正确显示

    当前位置:我的异常网» Oracle管理 » 两个数据库怎么保持数据正确显示 两个数据库怎么保持数据正确显示 www.myexceptions.net  网友分享于:2015-08-26  浏览:23 ...

  5. CentOS全局配置JAVA环境变量,实现多个tomcat共用环境变量,不用再一个个tomcat配置

    vim /etc/profile 然后在最后加入下面的代码: export  JAVA_HOME=/usr/local/java/jdk export  PATH=/usr/local/sbin:/u ...

  6. C++中定义类的对象:用new和不用new的区别

    Point p1; Point *p2=new Point(); p1 由系统创建并释放,不用担心会出现内存泄露,但是生命期只有在本区域的大括号内,出了大括号就没用了. P2 是指针,要自己释放,用不 ...

  7. 在plsql里面怎么去掉空行_盐渍樱花怎么做?详细做法告诉您,一年都不会坏,学会再也不用买...

    盐渍樱花怎么做?详细做法告诉您,一年都不会坏,赶紧收藏学会它!樱花季说的就是现在,虽然到了飘落的季节,但是还是到处可见的樱花朵朵.俗话说:花无百日红.真的是啊,每年的三四月是最美丽的季节,到处花儿朵朵 ...

  8. java并发读取相同的文件_高效读取大文件,再也不用担心 OOM 了!

    最近阿粉接到一个需求,需要从文件读取数据,然后经过业务处理之后存储到数据库中.这个需求,说实话不是很难,阿粉很快完成了第一个版本. 内存读取 第一个版本,阿粉采用内存读取的方式,所有的数据首先读读取到 ...

  9. 投影转换_即插即用,办公投影不用愁:毕亚兹Mini DP转HDMIVGA转换器

    日常办公的时候一些办公小件也很有用的,就比如说HDMI,VGA的转接头,不起眼但是很实用.去客户那里汇报工作,笔记本没有VGA接口,结果会很尴尬,到处借,没有转接头就是接不了,所以索性还是自己入手一个 ...

  10. UDP客户端不用绑定吗IP和端口?

    2019独角兽企业重金招聘Python工程师标准>>> 书上都是这么说的,UDP客户端不用绑定IP和端口,操作系统会给它自动分配端口.... 但是虽然没有显示绑定,但是操作系统却似乎 ...

最新文章

  1. ELASTIC SEARCH 性能调优
  2. recycleview 嵌套高度问题_突破!10万荧光材料无一幸免,150年来都没有解决的问题,最近找到答案了!|史上最强荧光材料...
  3. jQuery日期弹出选择框Datepicker效果
  4. m3u直播源_教你创建电视直播源
  5. 启明云端带你一起撸ESP32开发板,玩转语音、彩屏
  6. DCMTK:OFStandard类中的double / ascii转换方法的测试代码
  7. geoserver的api接口_geoserver REST使用
  8. oracle 循环继续,oracle – 是否可以继续从异常循环?
  9. 云计算技术前景怎么样?
  10. 自己实现一个SQL解析引擎
  11. Java中对象的深复制(深克隆)和浅复制(浅克隆)介绍
  12. [SDOI2011]计算器
  13. iBATIS In Action:iBATIS的安装和配置
  14. 《Linux命令行大全》第2版来啦!这一版做了哪些更新?
  15. 佳博GP1124T的安装向导
  16. python收取126或163邮件
  17. 豆瓣上的一条关于泰坦尼克的影评5
  18. 相机PHP,C/C++、C#、PHP相机开发实例 大恒相机SDK
  19. draw.io软件添加常用字体
  20. 解决window 10 Edge浏览器下载速度太慢

热门文章

  1. 教你一个免费合并PDF最简单的方法
  2. 防止血糖飙升,你需要知道这12个技巧
  3. LabelImg生成的XML中width,height=0的问题
  4. 操作系统学习-6. 信号量
  5. C语言学堂在线测试题防丢失汇总
  6. 2.27学堂在线python学习笔记
  7. 对话刘晓庆:即便人生大起大落,也挡不住我的光芒
  8. 做好一个普通人 逐步地悟出自己的规划 才是可以走的路
  9. C++开发斗地主(QT)第二篇之牌的绘制与显示
  10. 深度学习入门之Python小白逆袭大神系列(三)—深度学习常用Python库