01 | 重新认识C++:生命周期和编程范式

你好,我是Chrono。

今天是专栏的第一节正式课。我想,既然你选择了这个专栏,你就应该已经对C++有所了解了,而且有过一些开发经验,甚至还掌握了一两种其他的语言。

苏轼有诗云:“不识庐山真面目,只缘身在此山中。”学习C++很容易被纷繁复杂的语法细节所吸引、迷惑,所以,我决定从“生命周期”和“编程范式”这两个不太常见的角度来“剖析”一下C++,站在一个更高的层次上审视这门“历久弥新”的编程语言,帮你认清楚C++最本质的东西。

这样,今后在写程序的时候,你也会有全局观或者说是大局观,更能从整体上把握程序架构,而不会迷失在那些琐碎的细枝末节里。

现在,我们先来了解下C++的生命周期。

C++程序的生命周期

如果你学过一点软件工程的知识,就一定知道“瀑布模型”,它定义了软件或者是项目的生命周期——从需求分析开始,经过设计、开发、测试等阶段,直到最终交付给用户。

“瀑布模型”把软件的生命周期分成了多个阶段,每个阶段之间分工明确,相互独立,而且有严格的先后次序,是一个经典的开发模型。虽然它已经不再适合瞬息万变的互联网产业了,但仍然有许多值得借鉴和参考的地方。

那么,说了半天,“瀑布模型”跟C++程序有什么关系呢?

其实,从软件工程的视角来看,一个C++程序的生命周期也是“瀑布”形态的,也可以划分出几个明确的阶段,阶段之间顺序衔接,使用类似的方法,就可以更好地理解C++程序的运行机制,帮助我们写出更好的代码。

不过,因为C++程序本身就已经处在“开发”阶段了,所以不会有“需求分析”“设计”这样的写文档过程。所以,一个C++程序从“诞生”到“消亡”,要经历这么几个阶段:编码(Coding)、预处理(Pre-processing)、编译(Compiling)和运行(Running)

C++程序的四个阶段

编码应该是你很熟悉的一个阶段了,这也是我们“明面”上的开发任务最集中的地方。

在这个阶段,我们的主要工作就是在编辑器里“敲代码”:定义变量,写语句,实现各种数据结构、函数和类。

编码阶段是C++程序生命周期的起点,也是最重要的阶段,是后续阶段的基础,直接决定了C++程序的“生存质量”

显然,在编码阶段,我们必须要依据一些规范,不能“胡写一气”,最基本的要求是遵循语言规范和设计文档,再高级一点的话,还有代码规范、注释规范、设计模式、编程惯用法,等等。现在市面上绝大部分的资料都是在教授这个阶段的知识,在专栏后面,我也会重点讲一讲我在这方面的一些经验积累。

那么,编码阶段之后是什么呢?

可能对你来说稍微有点陌生,这个阶段叫预处理

所谓的预处理,其实是相对于下一个阶段“编译”而言的,在编译之前,预先处理一下源代码,既有点像是编码,又有点像是编译,是一个中间阶段。

预处理是C/C++程序独有的阶段,其他编程语言都没有,这也算是C/C++语言的一个特色了。

在这个阶段,发挥作用的是预处理器(Pre-processor)。它的输入是编码阶段产生的源码文件,输出是经过“预处理”的源码文件。“预处理”的目的是文字替换,用到的就是我们熟悉的各种预处理指令,比如#include、#define、#if等,实现“预处理编程”。这部分内容,我后面还会展开讲。

不过,你要注意的是,它们都以符号“#”开头,虽然是C++程序的一部分,但严格来说不属于C++语言的范畴,因为它走的是预处理器。

在预处理之后,C++程序就进入了编译阶段,更准确地说,应该是“编译”和“链接(Linking)”。简单起见,我统一称之为“编译”。

在编译阶段,C++程序——也就是经过预处理的源码——要经过编译器和链接器的“锤炼”,生成可以在计算机上运行的二进制机器码。这里面的讲究是最多的,也是最复杂的,C++编译器要分词、语法解析、生成目标码,并尽可能地去优化。

在编译的过程中,编译器还会根据C++语言规则检查程序的语法、语义是否正确,发现错误就会产生“编译失败”。这就是最基本的C++“静态检查”。

在处理源码时,由于编译器是依据C++语法检查各种类型、函数的定义,所以,在这个阶段,我们就能够以编译器为目标进行编程,有意识地控制编译器的行为。这里有个新名词,叫“模板元编程”。不过,“模板元编程”比较复杂,不太好理解,属于比较高级的用法,稍后我会再简单讲一下。

编译阶段之后,有了可执行文件,C++程序就可以跑起来了,进入运行阶段。这个时候,“静态的程序”被载入内存,由CPU逐条语句执行,就形成了“动态的进程”。

运行阶段也是我们最熟悉的了。在这个阶段,我们常做的是GDB调试、日志追踪、性能分析等,然后收集动态的数据、调整设计思路,再返回编码阶段,重走这个“瀑布模型”,实现“螺旋上升式”的开发。

好了,梳理清楚了C++程序生命周期的四个阶段,你可以看到,这和软件工程里的“瀑布模型”很相似,这些阶段也是职责明确的,前一个阶段的输出作为后一个阶段的输入,而且每个阶段都有自己的工作特点,我们可以有针对性地去做编程开发。

还有,别忘了软件工程里的“蝴蝶效应”“混沌理论”,大概意思是:一个Bug在越早的阶段发现并解决,它的价值就越高;一个Bug在越晚的阶段发现并解决,它的成本就越高。

所以,依据这个生命周期模型,我们应该在“编码”“预处理”“编译”这前面三个阶段多下功夫,消灭Bug,优化代码,尽量不要让Bug在“运行”阶段才暴露出来,也就是所谓的“把问题扼杀在萌芽期”。

C++语言的编程范式

说完了C++程序的生命周期,再来看看C++的编程范式(Paradigm)。

什么是编程范式呢?

关于这个概念,没有特别权威的定义,我给一个比较通俗的解释:“编程范式”是一种“方法论”,就是指导你编写代码的一些思路、规则、习惯、定式和常用语

编程范式和编程语言不同,有的范式只能用于少数特定的语言,有的范式却适用于大多数语言;有的语言可能只支持一种范式,有的语言却可能支持多种范式。

那么,你一定知道或者听说过,C++是一种多范式的编程语言。具体来说,现代C++(11/14以后)支持“面向过程”“面向对象”“泛型”“模板元”“函数式”这五种主要的编程范式。

其中,“面向过程”“面向对象”是基础,支撑着后三种范式。我画了一个“五环图”,圆环重叠表示有的语言特性会同时应用于多种范式,可以帮你理解它们的关系。

接下来,我就和你详细说说这五种编程范式。

C++语言的五种范式

面向过程是C++里最基本的一种编程范式。它的核心思想是“命令”,通常就是顺序执行的语句、子程序(函数),把任务分解成若干个步骤去执行,最终达成目标。

面向过程体现在C++中,就是源自它的前身——C语言的那部分,比如变量声明、表达式、分支/循环/跳转语句,等等。

面向对象是C++里另一个基本的编程范式。它的核心思想是“抽象”和“封装”,倡导的是把任务分解成一些高内聚低耦合的对象,这些对象互相通信协作来完成任务。它强调对象之间的关系和接口,而不是完成任务的具体步骤。

在C++里,面向对象范式包括class、public、private、virtual、this等类相关的关键字,还有构造函数、析构函数、友元函数等概念。

泛型编程是自STL(标准模板库)纳入到C++标准以后才逐渐流行起来的新范式,核心思想是“一切皆为类型”,或者说是“参数化类型”“类型擦除”,使用模板而不是继承的方式来复用代码,所以运行效率更高,代码也更简洁。

在C++里,泛型的基础就是template关键字,然后是庞大而复杂的标准库,里面有各种泛型容器和算法,比如vector、map、sort,等等。

与“泛型编程”很类似的是模板元编程,这个词听起来好像很新,其实也有十多年的历史了,不过相对于前三个范式来说,确实“资历浅”。它的核心思想是“类型运算”,操作的数据是编译时可见的“类型”,所以也比较特殊,代码只能由编译器执行,而不能被运行时的CPU执行。

在讲编译阶段的时候我也说了,模板元编程是一种高级、复杂的技术,C++语言对它的支持也比较少,更多的是以库的方式来使用,比如type_traits、enable_if等。

最后一个函数式,它几乎和“面向过程”一样古老,但却直到近些年才走入主流编程界的视野。所谓的“函数式”并不是C++里写成函数的子程序,而是数学意义上、无副作用的函数,核心思想是“一切皆可调用”,通过一系列连续或者嵌套的函数调用实现对数据的处理

函数式早在C++98时就有少量的尝试(bind1st/bind2nd等函数对象),但直到C++11引入了Lambda表达式,它才真正获得了可与其他范式并驾齐驱的地位。

好了,介绍完了这五种编程范式,你可以看到,它们基本覆盖了C++语言和标准库的各个成分,彼此之间虽然有重叠,但在理念、关键字、实现机制、运行阶段等方面的差异还是非常大的。

这就好像是五种秉性不同的“真气”,在C++语言里必须要有相当“浑厚”的内力才能把它们压制、收服、炼化,否则的话,一旦运用不当,就很容易“精神分裂”“走火入魔”。

说得具体一点,就是要认识、理解这些范式的优势和劣势,在程序里适当混用,取长补短才是“王道”

说到这儿,你肯定很关心,该选择哪种编程范式呢?

拿我自己来说,我的出发点是“尽量让周围的人都能看懂代码”,所以常用的范式是“过程+对象+泛型”,再加上少量的“函数式”,慎用“模板元”。

对于你来说,我建议根据自己的实际工作需求来决定。

我个人觉得,面向过程和面向对象是最基本的范式,是C++的基础,无论如何都是必须要掌握的,而后三种范式的学习难度就大一些。

如果是开发直接面对用户的普通应用(Application),那么你可以再研究一下“泛型”和“函数式”,就基本可以解决90%的开发问题了;如果是开发面向程序员的库(Library),那么你就有必要深入了解“泛型”和“模板元”,优化库的接口和运行效率。

当然,还有一种情况:如果你愿意挑战“最强大脑”,那么,“模板元编程”就绝对是你的不二选择(笑)。

小结

今天是开篇第一课,我带你从“生命周期”和“编程范式”这两个特别的角度深度“透视”了一下C++,做个简单小结:

  1. C++程序的生命周期包括编码、预处理、编译、运行四个阶段,它们都有各自的特点;
  2. 虽然我们只写了一个C++程序,但里面的代码可能会运行在不同的阶段,分别由预处理器、编译器和CPU执行;
  3. C++支持面向过程、面向对象、泛型、模板元、函数式共五种主要的编程范式;
  4. 在C++里可以“无缝”混用多范式编程,但因为范式的差异比较大,必须小心谨慎,避免导致混乱。

课下作业

最后是课下作业时间,给你留两个思考题:

  1. 你是怎么理解C++程序的生命周期和编程范式的?
  2. 试着从程序的生命周期和编程范式的角度,把C++和其他语言(例如Java、Python)做个比较,说说C++的优点和缺点分别是什么。

欢迎你在留言区写下你的思考和答案,如果觉得对你有所帮助,也欢迎把今天的内容分享给你的朋友,我们下节课见。

精选留言

  • 忆水寒

    2020-05-06 18:56:22

    1、编程范式其实用的最多的就是面向过程、面向对象、类模板和泛型编程。
    2、C++的优点是运行效率高,毕竟比较靠近底层硬件了。C++的缺点就是面向对象的不彻底,多重继承确实比较混乱难理解。
    作者回复

    说的很好。

    对于第二点,C++不是不彻底,而是不存粹,毕竟它是面向对象的探路先锋,走了一些弯路,给后来的java等语言蹚了道。

    其实如果你愿意,完全可以在C++里按照Java的风格来写面向对象,这就是C++给予我们的自由。

    2020-05-06 19:28:29

  • Woturbo

    2020-05-09 12:01:00

    1. 生命周期是值得整个C++程序的开发运行过程,除编码外都是由编译器完成。像预编译、编译、链接的过程实际知道原理即可,达到出现问题的时候能够解决。
    编程范式就是编程思想(方法路),c++复杂的根源,包含了五种。功能是足够强大,但如果不合理使用,一味的去“炫技”,会不利于开发。核心思路是以可读性和可维护性为第一原则。
    2. C++静态编程语言,存在代码编译过程即把字符代码转化为机器码(二级制文件)。python是动态(脚本)语言,执行代码可以不经过编译,执行过程为解释执行,相比c++程序最终的二进制直接执行来说解释执行效率会低得多。但从编程范式的角度,python支持的主要的编程方式(过程、函数、‘面向对象’(鸭子对象))该有的都有,比c++更简单易用,官方库强大的特点(通用性强)。解析器可以理解一个中间层,它的存在可以提高python等动态语言的可移植性,而c++的可移植性相比之下是要弱一些,需要考虑abi和平台相关。另外c++的代码安全性高,反汇编难度很大。java我的理解是介于动态语言和静态语言之间,就不做过多比较。
    作者回复

    总结的很好。

    在C++里,所谓的鸭子对象,其实就是泛型。

    2020-05-09 12:59:21

  • 八曲长弓

    2020-05-06 17:40:37

    以前看过罗老师的《BOOST程序库完全开发指南》有不少收获,极客上看见罗老师Cpp课程毫不犹豫就买了,希望跟罗老师学习更多。
    作者回复

    感谢老读者捧场,有Boost的问题也可以在这里随时问。

    2020-05-06 17:50:18

  • 2020-05-09 10:40:19

    罗老师,面向对象和基于对象有什么区别?
    作者回复

    这两个广义上都属于面向对象,严格来说也算是有区别。

    前者强调统一用对象建模,多应用设计模式,对象关系复杂。

    而后者则相当于C with class,只把class当成struct来封装数据,继承、多态等高级特性用的比较少。

    2020-05-09 11:25:27

  • 土逗

    2020-05-10 10:15:52

    1、C++程序的生命周期,分为: 编辑代码 -》预处理器进行相关宏定义,typedef等替换 -》编译器编译成汇编代码,汇编器生成目标obj -》ld连接器进行相应库的链接 -》 生成的可执行文件其实就是这些obj的打包文件,如果是静态链接的话则还包含静态库的内容,如果是动态库则包含执行动态库的路径 -》执行起来成为一个进程 -》进程结束意味着该C++程序的生命周期结束了;

    我理解的C++的范式,就是C++支持编码的多种方式,支持面向过程,支持面向对象,支持泛型编程,支持函数式方式编程,支持模板元编程,经常使用的就是面向对象+面向过程+泛型模板

    2、C++对比Java,从编译的角度看C++需要预处理,并且最终会编译成二进制的机器码,Java编译成字节码,被Java虚拟机进行解释,而不是真正的机器码;
    我理解的C++的优点缺点如下:
    C++的优点:
    1)能够直接编译成机器码,是真正的跨平台代码;
    2)C++直接编译成机器码,则可以直接被CPU执行,而Java需要中间的java虚拟机解释执行,从开销看,C++的效率会高些;另外Java是动态类型安全语言,意味着需要由虚拟机来确保程序不会违反语言语义或访问非结构化内存,在实现层面上,虚拟机必须要频繁的进行动态检查,如是否为空指针,数组是否越界,类型转换关系等,这些都需要耗费不少运行时间,但是C++不需要,空指针,越界,果断coredump掉;


    缺点:
    1、从编译的角度看,要编译成二进制文件,预处理等其他繁琐的编译步骤,要比java直接编译成字节码要慢;
    2、C++在C++11之前没有内管里边做的很不好,对于新手不友好,在经验不足的时候容易出现cordump或内存泄漏的情况,C++11使用智能指针让内存管理方便不少;
    2、罗老师说C++中包含了五种“真气”,我的理解更简单,C++其实就是5种语言组成的集合,相比其他Java学习成本更加陡峭;
    作者回复

    总结的很好,有几个小错误要说一下。

    1.typedef是在编译阶段,而不是预处理阶段,这个后面讲预处理、编译的时候你就清楚了。

    2.直接编译成机器码,但这并不是跨平台的代码,而是源码可以跨平台,由不同的编译器编译成对应平台的二进制代码。
    Java等语言的字节码由于运行在虚拟机上,它才是跨平台的代码。

    3.C++编译慢还有一个原因,就是语法复杂,还有编译优化等等。

    2020-05-10 14:22:34

  • Carlos

    2020-05-06 19:20:37

    回答老师的问题并提出我自己的问题:

    1. 生命周期我比较熟悉, 这个过程可以用之前对编程范式了解不多, 今天头一次听说, 我觉得这个好像更是一种 "解决问题的习惯". 请问老师网上的 google c++ style guide 算不算是一直种范式?

    2. 比较 c++ 与 python:

    python: 语法简单, 而且 "互动感" 很强, 对 object 进行操作的时候可以一句一句运行.

    C++: 执行速度快, 优化空间大, 感觉写代码的时候在和内存说话, 自己知道自己在写什么.

    向老师提一个不情之请: 我的 C++ 是直接用英文学的, 希望老师多给出一些对应的英文帮助理解.

    再小小八卦一下, 老师您的英文名和这个有关系吗: auto start = std::chrono::high_resolution_clock::now();?
    作者回复

    回答的很认真,表扬。

    1.编程范式是一种方法论,指导如何编程,偏重语法规则。Google style guide是编码风格指南,还不算是范式。可以结合课程正文再理解一下。

    2.比较的挺好,一个是解释型语言,一个是编译型语言。

    3.C++的语法要素中英文翻译都比较规范了,如果纯英文有时候会有点别扭,有不清楚的就问吧,我给解答。

    4.这个名字来自于超任的《chrono trigger》,25年前的老游戏。

    2020-05-06 21:50:54

  • Geek_a6104e

    2020-05-20 20:44:12

    老师你好 请问面向过程和函数式编程有什么区别? 之前看有些资料上介绍 面向过程其实就是调用函数 所以我觉得面向过程和函数式编程貌似差不多
    作者回复

    面向过程是命令式的,就像是个流水线,而函数式编程是面向函数的,是函数套函数。

    两种范式虽然都用“函数”,但解决问题的思路是不一样的,等到后面讲lambda,还有容器和算法的时候可能会更好理解一些。

    2020-05-21 08:54:57

  • 谷鱼

    2020-05-15 11:34:43

    1.看到了生命周期和编程范式,C++的编译和预处理是这一类语言的共性,比较显式。比如常用的脚本语言就没有这么明显,python,php,js,ruby都是这样的,更多只能感受到编码和运行两个阶段,优化的参数也多是很常规的。
    2.优点和缺点我就不清楚了。公司用到了opencv,我才意识到C++的存在,但是不会去编码,会去理解它的常用语法,理解一些思路,这无疑说明,它的周期太长,适合团队开发,充分测试,无法多快好省,短平快。重武器也许都这样吧。go还友好一点
    作者回复

    C++的开发周期长成本高,所以现在适合做底层、比较稳定、核心的那些部分。

    2020-05-15 18:40:30

  • 酸葡萄

    2020-05-28 19:59:30

    老师,您好,编程范式讲概念还是比较难理解,特别是函数式编程,每种范式要是都能来段代码举例就好了
    作者回复

    往后面看,后面会慢慢讲,会有代码,到后面还有不清楚的再问。

    2020-05-28 20:56:42

  • 少年

    2020-05-06 22:42:27

    老师的思路确实给徘徊在入门与放弃C++的人提供了一条新路,听完很有感触。生命周期的阶段划分,预处理单独成段?为啥不叫编译预处理?
    作者回复

    预处理是C语言的传统,就是文本替换,不涉及语法,英文术语就叫pre-process,用原文来理解吧。

    2020-05-07 05:25:13

  • BrandonH

    2022-03-01 11:56:32

    生命周期指的是c++语言从编码、预处理、编译链接到执行的过程。编程范式用的多的主要有:面向对象 面向过程 泛型 函数式
    作者回复

    great

    2022-03-01 14:55:35

  • 唐聪

    2020-09-22 18:40:14

    1.1 生命周期是编程语言的共同点,从源代码变成机器码的过程;
    1.2 C++的编程范式,如同打篮球的技能包,三分或中投;目标都是要进球;

    2 用C比较多,过程语言if else;
    作者回复

    C/C++的生命周期和其他语言还是不同的,有一个独特的预处理阶段,而很多脚本语言是解释型的,也就不需要编译。

    因为这些区别,所以C/C++与其他语言就有了不同。

    2020-09-22 20:17:05

  • 张飞Dear

    2020-07-29 20:41:46

    1,C++生命周期:每个生命周期各有各的特点,①编码阶段是一个程序员构建整个软件的时候,是很重要的。②预处理阶段 工具进行处理 对此不是很了解,主要是通过预处理命令进行相应的替换。③编译过程很重要,这一阶段能够检查出编码产生的语法错误,能够生成不同平台的代码,也是跨平台的实现。④运行阶段也是能够检查编译器所不能报出的逻辑上bug。
    2,编程范式:之前不了解,只是知道有数据库范式,和这个不太一样,之前只是知道 C++有这么多功能,但是以这种范式解释是第一次见,罗老师讲的更通俗易懂,C++最重要的还是面向过程和面向对象以及泛型。后面那两种 在平时开发 用的不多,而且也可以通过比前三种来进行替换。

    3,了解过一点Java ,Java的优点是一次开发,所有平台都能使用。但是在运行时需要虚拟机来进行,效率上指定是不如C++的。 Java不能直接操作内存,在内存管理上不如C++。
    作者回复

    总结的很好,态度很认真。

    java虽然运行效率不如C++,但它由于有虚拟机,可以跨平台,而且不会有那么多的底层麻烦,所以更稳定一些,适合更高层次开发业务,所以才会有那么多的框架、系统。

    2020-07-30 08:53:06

  • ericluo

    2020-05-18 17:51:33

    罗老师,您好
    我一般看到生命周期,第一时间想到应用的启动到退出之类内容,所以会不会其它的读者也有相同的感觉
    作者回复

    是的,一般说的可能是程序的运行生命周期,我在这里把它扩大到了从编写到运行,主要是为了方便讲解C++的各种特性。

    2020-05-19 08:52:46

  • 拉普达

    2020-05-07 21:54:22

    1、C++生命周期中的预处理和编译是其特有的环节,编译执行是其高效的基础,相比而言java、python等解释执行的语言更有优势。但正是出于效率的考虑,C++的编译执行给程序员提供了足够的灵活性,但也提供了无限出错的可能,这也是其难学的原因。另外,关于C++的预处理和编译,希望老师在后续课程中多花些时间讲解一下,之前每次遇到Link Error,都不知道怎么处理。
    2、编程范式方面,个人觉得开发应用程序,面向过程和面向对象是基础,外加使用泛型即可满足大部分要求。函数式编程目前还没有深入了解过,如果团队中没有80%的人掌握,不建议使用。
    作者回复


    1.编译链接出错确实是很多C++程序员最头痛的问题,报错信息一大堆,很不友好。我的方法是去搜索引擎里搜一下错误文字,通常都能够找到答案或者提示。

    2.理解的很对,C++的应用水平取决于团体的整体水平,但如果总停留在低水平既不利于项目也不利于自己,可以通过培训、讨论来提高,这样C++就会越用越爽。

    2020-05-08 06:03:29

  • wuwei

    2020-05-07 19:17:57

    学过一点点cpp。
    生命周期:了解到cpp的从写到运行的机制,不再是黑盒子;
    编程范式:面向过程,面向对象,泛化编程,函数式编程,模版元这些范式让我明白,范式有自己的特点和优势,清楚的掌握他们,将他们作为工具充分利用,应该可以避免混淆;

    cpp与python比较:
    python:简单、易用,可以快速实现算法,不过很慢;
    cpp:难学难用,编程过程中要考虑很多关于内存的问题,不过运行超快;
    同样的算法,cpp写出来比python快好几个量级

    最后的问题:多线程、重载、多态、智能指针、动态内存,这些平时用的多不多,学习的时候应该注意什么?
    作者回复

    总结的很好。

    你提的这些特性,多线程复杂但有用,重载、多态学起来容易但有很多陷阱,智能指针是好东西,后面我会专门讲,它和容器都可以用来管理动态内存。

    我的建议是先学简单的特性,复杂易错的特性少用,有经验了再扩大使用范围。

    2020-05-07 21:23:04

  • William Wang

    2024-10-23 17:28:38

    p1:
    (1)生命周期:
    【编码阶段】我们需要遵循优秀的编码规范,小到函数和变量命名,大到多线程锁的分配、悬空指针的处理,都需要在编码阶段尽量避免产生问题。
    【预处理】阶段是对带#的预处理命令进行处理,包括并不限于#include中包含的文件在源代码文件中展开,对#define进行展开等,生成.i或者.ii文件。
    【编译】阶段进行语法分析、词法分析、目标代码生成等,生成汇编代码,产生.s文件。
    【汇编】阶段会根据汇编指令和特定平台,将汇编指令翻译成二进制形式,生成.o文件。
    【链接】阶段会合并各个二进制文件,合并符号表,进行符号解析,最终生成可执行文件。
    【运行】阶段会根据代码中new或者malloc动态分配内存,创建对象,debug模式下,运行阶段软件崩溃系统会产生coredump文件来保存崩溃时函数调用栈的内存副本。
    (2)编程范式:
    【面向过程编程】就是c语言的编程模式,通过if-else,while,for等基础编码模式来实现功能,这种范式的问题在于对大型软件不够友好,各个功能之间拆分难度大,但是上手简单,代码易读,属于比较初级的编程范式。
    【面向对象编程】是c++相较于c语言先进的地方之一,也是学习c++必学的一个内容,通过封装、继承和多态的属性来拆解功能、进行系统设计,最终到完整的设计模式,都离不开对象的概念。
    【泛型编程】是一种编程思路,或者说软件设计方法,通过一定的技术来让一个模块可以进行复用。在c++中泛型主要通过模版元编程实现,包括类和函数的模板。
    【模板元编程】是通过使用template关键字,来将类型作为变量,提高软件的可扩展性。
    【函数式编程】是一种通过函数的求值和组合来构造程序的编程范式,通过重载()括号运算符来实现,比如STL算法中的sort就是通过函数式编程的方式来实现的。

    p2:
    (1)java:java代码通过javac编译器将代码转换成字节码文件.class,这个字节码文件在任何JVM都可以运行,这一步是java的编译,然后在程序运行的时候JVM再对字节码进行解释或者实时编译为机器码再运行,而c++运行时不会再需要进行编译或者解释等操作,这就导致c++的运行性能更好。但是因为java是通过JVM对class进行解释,所以java的跨平台性比c++要好。
    (2)python:python是一个解释型语言,每执行一行代码解释一行代码,运行速度远远不如c++,但是python依托于python解释器来运行代码文件,所以跨平台性也很强。
    (3)三种编程语言在编程范式上基本一致,作为高级语言在功能上保持了一定的相似性。
    作者回复

    very nice.

    2024-10-25 09:53:58

  •     

    2023-09-20 08:05:43

    我觉得C++的优点和缺点是并列的,就像硬币的正反面。
    优势:
    1. 足够贴近底层,运行效率很高。
    2. 功能强大,几乎所有的编程范式都能在C++中找到。
    缺点:
    1. 功能过于强大导致很难使用好,一个值对象和地址对象就能让我学几个小时还不太明白。而且新加入的特性其实是为了解决一些历史问题的,但是对于不了解C++的人来说根本不能理解新特性的用处,加重了学习负担。
    2. 没有一个好用的库管理平台,Java有maven。但是C++的编译等需要手动去链接添加库,甚至要先自己编译安装好这些库。对新手来说太劝退了。
    3. 一个C++新手非常主观的想法,C++的源代码太难读了。由于关键字太多再加上typedef这种别名的使用,读别人代码的过程要花太多时间在这些东西上。
    作者回复

    agree。

    2023-09-20 11:50:27

  • CoderAndy

    2022-12-07 08:00:44

    我有一问,烦请作者解惑。为何说用模板可以让代码运行效率更高,或者说这个说法的前提是什么?
    作者回复

    不是太准确吧,应该说是泛型更好一点。

    如果泛型编程用得好,可以减少使用RTTI、继承、虚表指针的成本,因为一些工作都是在编译期完成的。

    2022-12-07 11:47:08

  • 夕林语

    2022-10-14 11:28:24

    1、编程范式说白了就是编程风格,我平时应用比较多的就是面向对象、泛型编程、面向过程及函数式编程;
    2、从编程范式的面向对象来讲,C++和Java的区别就在于垃圾回收机制,也就是内存管理的不同,C++自己进行管理灵活高效但是容易出问题,Java就比较傻瓜式,一切交给虚拟机
    作者回复

    great

    2022-10-14 11:42:55