C++到底有多难?难在哪里?

每日一发小视频


刚好最近在学习C++,以前又有其它语言的编程经验,所以对此刚好有一定发言权。

C++是所有主流编程语言中最难掌握的语言!这一点基本上得到了公认。“主流”一词不能少,大致可以认为是各类计算机语言排行榜中前50名了那些。有些搞怪的,用来“玩”的语言可能比C++还难,但是它们不主流,也几乎没有谁真正用在生产环境,所以没有必要讨论。还有少数人认为最难的主流编程语言是汇编或LISP。这也是有道理的。不过不管怎么说,说C++的难度处于主流语言中前三位,就更加无懈可击,谁也否定不了。

我们这里讨论难度,主要都是以纯语言和核心标准库函数来说的,没有包含衍生的整个生态系统。比方说说JavaScript的难度那就是纯JavaScript,而没有包含jquery、vue、node.js等。再比如讨论JAVA难度,同样不包含安卓开发、spring甚至hadoop。再比如Python就不包含numpy、django甚至人工智能。

就我接触过的一些编程语言,JAVA、C#、Python、PHP、JavaScript、Go、C、R、scala、F#,它们在纯语法上,和C++的难度完全不在一个重量级!一种小巫见大巫的感觉。我刚加入一个C++团队,凡是接触过其他语言的,都说C++太难了。而有部分成员说C++简单的,一看都是刚毕业没有几年,只玩过C++而不知道其他语言的(一种初生牛犊的感觉吧)。

说了这么多废话,下面开始讨论为什么C++难,难在哪里。写的比较随意,想到哪里写到哪里。

第一、C++直接编译成本地代码

本地代码,就是直接可以在操作系统上运行的,不需要借助其他进程去引导它。C#、JAVA是运行于虚拟机的,Python、JavaScript是需要解释器的。也就是这些语言离开了虚拟机或解释器就运行不起来。但也正因为如此,它们才变得相对简单。因为虚拟机和解释器屏蔽了底层的很多细节。比方说你用JAVA写一段代码,你甚至都不需要知道到底操作系统是Windows还是Linux,你眼中的内存也仅仅是虚拟机上(简化的)内存。而C++不得不考虑底层的很多细节,导致很难。同样需要考虑底层的还有C、Go、rust等。单从这个角度看,这类编程语言是同一难度级别的。

第二、C++没有完善的自动垃圾回收机制

当我们一提到C/C++,大概首先想到的就是它们的指针。指针是C/C++的精髓,同样也是难度的根源之一。JAVA、Python等很多编程语言都是没有指针的。因为它们的虚拟机或解释器自带自动垃圾回收。指针实际上就是内存地址。当我们新建一个对象时,必须向操作系统分配内存(内存地址、指针),而对象使用完毕后,又应当回收。最常见的问题就是忘了回收或者其他变量正在引用就提前回收了。比如一个函数申请了内存,到底是该函数负责回收还是调用方负责回收?而带垃圾回收的语言,编程者完全不用操心这些事,完全不需要知道内存是如何分配的,该谁来回收以及如何回收。自动垃圾回收有利有弊,利是对开发者简单,弊是运行效率相对低下。C/C++是注重运行效率而牺牲了简单性。

第三、C++使用大量的预编译

在没有预编译的语言中,采用if else以及函数来完成类似的功能。比如if 32位操作系统该怎么做else怎么做。但是这样的代码最后是会运行的。而预编译时,假如不是32位操作系统(编译阶段就已经知道),相应的代码不会编译,这样就降低代码大小,且少了一个if else判断,效率更高。而预编译中的宏则是直接替代,防止了函数调用。函数调用也是需要损失性能的。正是这种过分强调性能,导致预编译被大量使用,给代码阅读和调试带来极大的不方便。

第四、C++历史包袱太多

C++是上世纪80年代的发明,还是比较古老了。在长期的发展中,存在大量的历史问题。比方说,一个字符串处理,就千奇八怪,它甚至都没有字符串类型这一说法。STL里有std:string,但也不是唯一的或做多的选择。相反,在其他所有现代语言中,字符串如何处理,都有几乎唯一的选择。C++选择太多,一方面你必须面临如何选择的问题,另一方面为了看懂别人的代码,你还不得不学习其他的选择是如何做的。历史包袱,就是说为了兼容以前的代码和以前的规范,不得不使整个系统非常复杂庞大。我们就说说Python吧,大家都知道目前有一个问题就是Python2.x和3.x的问题。你看,Python就果断地抛弃了2.x这个包袱(新版不再完全兼容老版),否则也会越来越复杂。C++没有这么做,因为老系统太多了,而且用的人多,根深蒂固,基本不可能推翻重来。像Go、D、rust这些新兴语言想取代年老的C++,都一直没有成功。如果C++想甩掉历史包袱(变成一门新的语言),那和rust、Go等又有什么区别?

第五、C++没有一个唯一的大东家

我们知道很多语言背后都有一个团队在运营,它们有绝对的权力或者说叫话语权,比如微软的C#、甲骨文的JAVA、谷歌的Go。Python(准确地说是cPython),也有唯一的开源项目,统一行动。再看C++,它不隶属于任何一个团队,它没有唯一的编译器开发商。微软的msvc,Linux的g++,还有clang等等。这么多厂商,谁也不占主导地位,谁也不听谁的。最后只能成立一个C++标准协会,大家协商着来,相互妥协。这种相互妥协,导致C++变得异常复杂,既兼容这个又兼容那个,甚至可以说是个“怪胎”。

第六、C++编译器太多,风格不一致

这个其实是上一条的延续(篇幅太长)。刚说了C++没有哪个厂家一家独大,靠标准协会协调。C++标准异常复杂。甚至有个词语叫做“未定义行为”。同样的代码,在这个编译器可以运行,在另一个编译器不行或者结果不一样,这种情况太多了。迄今为止没有一个公认的严格的C++规范,C++是非常自由的。自由就意味着难度大。Python为什么简单,就是因为它不自由,连变量名如何写,代码缩进都中规中矩。风格一致。不过也有其他语言和C++相似,比如JavaScript,它也是多厂家,标准不统一,风格不一致。

第七、C++语法博大精深

上面说了那么多,强调的都是背后的原因,那具体说来,到底C++难在哪里呢?这个不好说,下边只是我的理解,简单罗列出来。复杂的const和static语义。指针运算,取地址运算,引用,比如*、&、&&。模板与泛型。函数式编程。构造函数、拷贝构造函数、赋值构造函数、移动构造函数、析构函数。多重继承。

第八、第三方库不多

相对说来,C++主张从轮子造起,第三方库不是太多。很多看似简单的功能都得自己实现或者拼命地找库。一般说来,C++使用时间长了,就掌握得更好,所谓越老越吃香。因为可以不断积累库函数。而类似JAVA、Python这种,一方面标准库就自带,另一方面,遇到问题,网上一搜索,拿来就用。像线程、XML、json、sqlite3、TCP、http访问、crc32/md5,像这些如此基础的功能都没有提供自带标准函数。


犍为真人


C++是在C语言基础上发展而来的,学过C语言的程序员再来学习C++会更会入手,当然C语言也不是很好学,更何况C++要比C语言难一点。

第一从语法来说,C++编程语言还是比较简单,只要掌握C++编程方式与常见的java,PHP都很相识。

第二是抛异常,C++不像其他编程语言简单的打印就可以看出错误地方,C++需要编译出来在运行,但是编译过程很难发现有错误信息。

第三C++没有标准类库,不像python到处都是免费的类库可以直接使用。

第四语言设计上的复制性,主要体现在继承、封装、多态等等。

虽然C++是比计较难学的一种编程语言,但是它的市场很大,大型游戏开发,科技算法,网络软件开发,操作系统等领域。


常青春科技


个人感觉国内多数人混淆了两个概念:编程语言的语法知识和编程能力。多数人刚学习时,重心花在庞大、全面的语法细节中,结果如在大海中划个小船一样,最终迷失了方向而放弃。但在实际编程过程中,多数时间使用到的语法很少。

因此,真正想进入编程行业,培养编程能力更重要。只要编程能力上来了,再掌握编程语法要容易得多。

编程能力体现在C语言上,就是解决问题的流程细节中,简单说就是会画解决问题的流程图。而对于C++语言,主要是系统构架上,体现在掌握类之间的关系、对象之间的关系。

教人会点语法容易,因此高校与培训机构多偏于这方面。但培养人的思维与观念,太难了,谁会去做啊!


分享到:


相關文章: