什么时候用 C 而不用 C++?

78 篇文章 1 订阅
62 篇文章 0 订阅

从事 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的方法f

    return 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++编程的小伙伴,如果你想更好的提升你的编程核心能力(内功)不妨从现在开始!
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值