franciscochonge
发表于 2021-3-23 11:19
2个原因。
第一个是有很多庞大的系统是用c和c++写的,想要维护他们,换一种语言和编译器不现实。
第二个是,c和c++依旧是各自领域内的no.1,无可替代。比他们快的没他们好用,比他们好用的没他们快。至于和他们一样好用有效的没有垃圾回收高效低级的语言……为什么你不直接用c/c++呢?
--------------------------------------------------------
哪个程序员在前进的途中如果有前辈跟你说不要学c/c++,他基本在骗你。
哪怕真的有人没有学,或者没有实际当中维护过c项目,
但凡是有点见识的也不会跟你说c++要被淘汰了这个话。
可能在遥远的未来会有这样的事情发生,但是目前来看还是太没谱了。
better c或者better c++的声明不知道有多少了,
然而现在c和c++依旧在自己的领域独领风骚。
所谓市场份额变小了,无非是别的领域用更方便更高级的语言的应用范围更大,更广导致的。
毕竟c/c++是必要的低级语言不代表他们在所有领域都有不可替代性。
这和c系列要被淘汰是两回事。
Baste
发表于 2021-3-23 11:25
先说C语言为什么没被淘汰:
C语言在所属的领域里是唯一,连竞争者都没有,完全的垄断市场。只要涉及底层操作系统的东西,C语言就是唯一选择,只要涉及算法,C语言还是独一份,到了编译器,还是C语言,还有什么单片机、嵌入式这些也就C++可以竞争下,简单的说,除了企业级的编程,其他都是C语言。
接下来说说C++为什么没被淘汰:
1.在游戏和工具领域仍然是主流
首先是游戏领域,Milo Yip表示——
程序员必须使用C++框架/库,如大部分游戏引擎(如Unreal/Source)及中间件(如Havok/FMOD),虽然有些C++库提供其他语言的绑定,但通常原生的API性能最好、最新。
其次是工具领域,无论是网络安全还是杀毒软件,C++仍是主流语言。
2.很多领域需要极高的性能和控制性
需要程序员压榨每一分硬件性能的地方并不多,特别是现在的服务器核心数很多,只要能充分利用多核心,每个核心没有完全挖掘也是可以接受的。
一般来说,需要压榨硬件潜力的领域有:
1、操作系统
每个人每天都要用操作系统,这一块的性能哪怕提升1/1000,全球计算机加一起也是相当可怕的。
2、游戏引擎
更好更酷的游戏是主机硬件进化的主要推进器之一,而游戏一旦卡顿,基本就没法玩了,这个领域提升性能和可控性有无限需求。C++一直以来都是编写游戏引擎的首选语言,而且几乎是唯一语言。
3、嵌入式程序
单片机的硬件性能很弱,存储空间极小,C++就派上大用场了!
4、加密与安全方向
这个领域和操作系统类似,每个人每天都会用到。所以用C++来优化很有必要。
国内C++的招聘需求其实很大的,看这里:
现在的市场对 C++ 的需求大吗?另外,担心C++学不会?可以看看我的这个高赞回答,给出了一些系统学习C++的建议:
用一年时间如何能掌握 C++ ?不要担心学习C++之后找不到工作,退一万步说,掌握了C++再去学习其他语言,只能说:非常容易。
最后献上C/C++的一份修炼体系图,希望对大家有帮助:
另外,程序员多刷算法题好处多多,算法厉害的人进大厂非常容易,这里送一本阿里P8大佬撰写的算法笔记:
BAT大佬的刷题笔记,进大厂必看!
祝大家前程似锦,在编码的道路上一马平川。
码字不易,希望大家不要吝啬自己的鼓励,给我 :
@findyi
一个点赞,鼓励下我!
franciscochonge
发表于 2021-3-23 11:33
编程语言也是有地位的分级的。非严格地说,封装层级越低,地位越高;封装层级越高,地位越低。
你能问出这个问题我假设你有编程基础,并且我认为已经接触过封装层级比较高,比C“好用”的语言。因此心里有一些朴素的对比,并且你能看的懂我在说什么。
往最底层讲其实所有的程序都是在跟硬件打交道。不过我们今天不用谈得那么深,就把“操作系统”当作“最底层”来谈,所有的程序,都是在跟操作系统打交道,换句话说就是各种姿势花式调用操作系统 API 而已。
你在 linux shell 上跑一个命令,本质上是在跑一个已经写好编译好的程序,程序里面调用各种 linux API 执行操作并且把输出信息打印到屏幕上或者写入文件(注意打印到屏幕和写入文件本身也是在调用操作系统 API)。以我常用的 CentOS 为例,/usr/bin 存放系统命令程序、/usr/include 存放系统头文件、/usr/lib 存放系统库。同时自带 gcc 容许“性感码农,在线编程”的存在。而这些 API 全部是 C 语言实现。换句话说,大多数情况下,只有 C 可以直接跟操作系统打交道。C 的地位是最高的。
同时也正因为 C 的封装层级低,你接触不到,所以你才会有这样的疑问。拿 Linux 举例是因为简单直观,在 Win 和 Mac 上,道理仍然是相同的。
加深理解:打开你家 Python 的根目录,看看里面是不是也有两个文件夹分别叫 include 和 libs?打开看看里面有什么?
你所使用的“好用”的编程语言,其实都是对其下层语言的高一级封装。上面提到的 Python,其实就是对 C 的封装。Python 本身其实严格说并不是“编程语言”,而是“脚本”。一行一行的 Python 代码其实都是命令,每执行一个命令,Python 解释器会调用相应的下层 API。
其他语言也是如此。各自处于各自的封装层级,各司其职而已。很多情况下不用 C 直接开发应用软件的原因正是其封装级别太低,需要造很多中层轮子,开发难度过大,开发效率过低。Java 一行代码可能会代替小几十行 C,但并不意味着操作系统所做的工作减少了。只是你的开发工作减少了,开发效率提高了而已。编程语言替你做了很多你不需要关心的事情。
C++ 因为其拥有兼容 C 语法可以直接调用 C 库的优势,因此在编程语言中的地位也是无可替代的。
讲了那么多,现在回到你最初的问题,也就不言自明了。
HuldaGnodim
发表于 2021-3-23 11:42
因为不管怎么说都好,或者现代语言有多高级易上手,这个世界上始终需要一种猿语直接操作机器模型,没有gc,没有运行时信息,精确控制机器的一举一动,不多做不少做恰到好处的做。有了这个牢固的基础,方可以在上面做各种文章。所以,C语言无论如何是不会过时的,可能其运用领域日渐缩小,但是会一直存在。作为机器模型的抽象,C语言做得刚好恰到好处,可能对机器能力的描述不太充分,比如并行运算,但是真的瑕不掩瑜。并且C的语法又灵活,对于敢直面内存搞底层的黑客来说,实在是再称心如意不过的猿语。
但是,C语言的最大问题也是抽象恰到好处,只满足于机器模型,在很多情况下就显得抽象能力不足,所以我们就希望在不放弃对机器的精确控制力的前提下,又有着更好的代码表达方式(语法糖),这些新形式的代码,虽然一行代码能实现之前要写好几行的效果,但是其对机器的控制细节依然还在猿猴的预料之中,不为不需要的功能付出任何代价,就是其最好的注脚。(比如GC,其表现就完全不是猿猴所能把控的,gc啥时候回收对象,回收那些内存,一切都不是猿猴所能预料的)。所以除了C语言,我们还需要C++,就这样。
这本来是很好的设想,而且,刚刚面试的C++面试是带类的C,也确实能提高生产效率。但是一直以来,大C++被两大麻烦所纠缠。以至于很多时候,某些人使用C++来开发的进度比不上另外某些人用C来做同样的业务。
一是语言的难学难用,这个就不多说了,虽然C++11给其打了鸡血,又苟延残喘了一把,比之前好用很多,但也增加了太多新特性,对很多人来说,这就意味着要加大学习成本了,尽管有些人,新的语法一看就懂拿来就能用,但对多数人来说,这可能也漫长。不过这也没什么,也实在不能太过苛刻。因为一种语言,只要胆敢在机器模型上提供强大的抽象能力,那么它就一定不简单,所以只好把压力放在猿猴这边,成本始终是要付出的。更何况C++还要完全兼容C的丑陋语法,C++的语法,奋斗到现在没有崩盘实属难能可贵。试对比rust,有着和C++一样的伟大抱负(机器模型上的高抽象能力),却完全没有C++的包袱(从一开始就完全不准备兼容C),看看里面搞了多少概念,并且个人认为,rust的抽象能力就远远比不上大C++,rust不管是底层操作还是高级抽象,都对C++做了很大的阉割。
C++最大的问题还是库,一直以来,坊间流行的C++库,stl,boost,gtest,Loki,各种json xml库,……,没有一个是能让猿猴用以写业务代码写得开心的,就更别提垃圾mfc ace了。不说别的,就单单只是字符串操作就行了,没有一个库的字符串实现能让人满意,要求基本够用,接口干净,性能过得去,二进制复用,就只是这些简单理所当然的正当要求,遍观所有的字符串类,stl的string,cstring,qstring,fbstring等等,居然用起来都存在这样那样的心智包袱。迄今为止,C++圈子里面,就没有一个拿得出手的库可以满足平常的业务开发,其实,这也可以理解,因为破c++就连字符串的事情都做不好,还有何面目搞其他事情。这个事情让人痛心疾首,大C++的功能不可谓不丰富强大,人才也不可谓不济济,发展历史更不可谓不悠久,但是就没有及格的通用基础库。任何其他语言都不存在C++这样的尴尬,就不提java,C#这傲世双雄,哪个语言不是有配套的官方标准库,很有利于开发,新手学完语法没多久,就可以用库做点实际的事情。就连C也没有C++库的麻烦,反正语言抽象能力差,基础框架这事要做也做不好,马马虎虎,不用那么多纠结,这反而很有利于大力出结果,就C++猿猴背负着一堆的心智包袱在盘算用什么语法点来写代码,是template,还是虚函数,还是多继承,编译时间重要还是运行时重要……。就算是好几年的C++老手,也做不到其他猿语新手的开发效率,可耻悲哀。
是什么导致C++的通用库开发如此困难重重?归结起来,不外乎两大原因,统一的内存管理与统一的运行时信息。几乎现存C++库上的所有不良行为弱鸡功能包括template以及编译时间,都和这对拦路虎息息相关。而很多语言从一开始就从语言层面上集成了这两大功能,有了这两个坚实的基础,通用库自然搞起来得心应手。当然,C++要坚持零惩罚的抽象,要坚持不为不需要的功能付出任何代价,自然也就没办法在语言层面上提供完备的支持,但是并不表示就做不到统一的内存管理以及运行时信息,更不表示就能忽视它们。只可惜,所有的C++在这两点上,要么就回避要么就重视不足。
内存管理和运行时信息,这两个问题不解决,通用库的开发难度和工作量就会变得很巨大,而且劳民伤财出来的效果还很不好,比如stl,够惨淡经营了,够呕心沥血了,够集思广益了,但是没有直面内存管理和运行时信息这两大痛点,相反还采用头文件复用的方式,以及template的魔法,通过模板参数等旁门左道的邪术来回避,自然,就大力出垃圾,stl难以二进制复用,xml json 数据库读写等序列化操作,以及io,不管是易用性还是灵活性还是运行性能都是一团糟糕,而且还编译时间漫长更兼二进制代码膨胀。当然,用stl来搞搞算法以及数据结构的题目,还是可以的。而且stl还带起一股头文件复用的邪风。唯一对运行时稍微重视的库也就只有QT了,可惜这货的运行时信息并不完备还明藏私货,内存管理上也乏善可陈。
一个坚实的通用基础库对于C++来说,再怎么说重要都不为过,因为它可以指引代码的追求目标,摆脱C++复杂的语法,忘记内存管理细节,避免template关键字的出现,将C++当做是弱类型的动态语言同时又兼具静态强类型的好处,击退漫长的编译时间……。标准委员会在通用库上的保守不作为,迟早要让这门语言进入冷宫,现在市面上C++的学习者越来越少,再这么下去,猿语将不再猿语,C++要被淘汰的伟大日子的降临,指日可待,可是这并不是猿语的错,而是猿语官方组织的无能
FeastSC
发表于 2021-3-23 11:52
因为计算机行业的大部分基石软件,也就是那些基础设施,比如编译器,操作系统,数据库引擎,驱动程序等等,都是用C/C++来写的。这些程序就像是行业的基石,牵一发动全身,完全没有可替代性。淘汰C/C++,呵呵呵,做梦去吧
franciscochonge
发表于 2021-3-23 11:59
不妨探讨一下什么情况下C/C++会被淘汰。
第一,失去了赖以生存的土壤。更先进更流行的操作系统出现,且不支持C API。
第二,有更好的语言全面胜过C/C++。
第一条短时间内基本没戏,Windows/Linux/Unix三分天下,短时期内不大可能发生改变。
第二条可能性比第一条大,rust声势浩大,大有取而代之之意,不过就目前来看,威胁还不算大。
其他诸如Scala/go/Java等会在特定领域挤占C++的空间,对C影响不大。
所以现在谈淘汰C/C++为时过早。
RecursiveFrog
发表于 2021-3-23 12:05
因为其他语言都是渣渣.
unityloverz
发表于 2021-3-23 12:14
我先说说主要结论,主要原因有两个:历史遗留问题,更新成本和教育问题(程序员来源)
历史遗留是很好理解的,只要还有旧的代码要继续运行,即使一门语言再不好也会有人继续使用维护已有的代码(只不过我们也可以认为这种语言已经死了)。考虑到人们已经用C/C++写了大量的基础设施,把它们全部替换是大量浪费资源(就好比现在5G,4G,一样,出了新的更高速的通信技术,旧的仍然保留下来,就是因为全部更换实在是太浪费了)
然后是更新成本,即使这世界上存在这一门比C与C++更加好用的编程语言,更加高性能,接近底层,人们也不一定就会投入这门语言中。因为获得的收益可能完全小于迁移成本。别忘了,在当今竞争激烈的商业时代,如果一个代码运行的好好的,谁也没有动力要乱改这些代码。而且这个东西是由供求关系决定的,如果大公司有需要C/C++(因为各种各样的原因),C/C++就完全不会被淘汰,就一定会有人继续学习。
我想说的是,教育才是C/C++始终能够深入人心的重要原因。
很多CS的人在大学阶段受的教育都是用C/C++语言(当然也有别的语言,只不过前面两个是必备的)来传授的,比如操作系统原理,计算机架构,并行计算(很大一部分原因就是这些基础设施也是用C/C++写的)。为什么用C/C++呢?难道是因为大家在写作业的时候需要用到高性能吗?是因为C/C++一定就是最适合的所有这些问题的语言吗?
理论上说如果只是传授这些计算机知识的原理的话,我们完全可以发明一门基于伪代码的语言(就像大多数书上的一样),它要满足以下要求:
1.它很简洁直观,使得我们便于集中精力到我们要研究的问题上。
2.它反映计算机底层的细节,比如说应当手动分配内存,比如应该是编译的。
3.因为我们不需要用太多的抽象,所以类型系统应该比较简单,不要有花里胡哨的泛型等玩意。
这些要求很合理,作为教学的工具自然不要太复杂,毕竟教学时间也是有限的。
满足这三个要求的东西的编程语言,形式上就要等价于C/C++。
首先我们应该选择一门静态语言,因为一般静态语言才能编译(成便于研究和debug的机器码),然后因为1,3我们需要一个配备有简单的类型系统的编程语言。什么类型系统最简单(最符合直觉),基于简单lambda演算的语言肯定最简单,没有一点多余的抽象,再加上没有自动内存管理我本质上我们就得到C了(当然指针是一个问题,因为可以有和C类型系统等价但是不支持指针的编程语言,但是因为我们要求接近机器底层,所以对于地址的抽象还是要有的)。。。再复杂一点的类型系统我们就可以得到一个面向对象的语言了C++(现在是基于模板了,所以面向对象一斤是不准确的了)。
所以实质上我们要同时满足1,2,3要求的语言就寥寥无几,再加上C/C++在工业界有很大的应用,所以干嘛不用它们来教书?还方便同学们动手实践呢!
但是这不代表别的编程语言就不能很好的管理它们的内存,不代表别的编程语言设计上就不如C/C++,不代表别的编程语言就不能很好利用CPU了(我这里说的主要是静态编程语言)。最重要的问题是,大多数C/C++以外的语言有着很复杂的抽象(例如Haskell),要是我们在刚学的时候就教这些东西,大家就会云里雾里的,什么是高阶函数,什么是类型变量(这又牵扯到类型理论)?但是一开始我们要学的东西是计算机底层的东西,不是编程语言理论,这些用于生产环境的高级编程语言很多时候又用抽象屏蔽了底层实现的细节(屏蔽细节不等于没有好好利用计算机底层,看起来不像机器语言,不代表最后执行起不像机器语言一样快),也自带垃圾回收(这一点就可以筛掉一大堆语言了),所以教起来效果就可能不好。要是我们用C这样就好解释了,每一个malloc对应着一个内存分配,结构体是一片内存划分成不同的域等等,但是Haskell就不好说了,谁知道一个sum type或者递归类型在内存里面怎么摆放的,是box了还是unbox的(你可以知道,但是要查文档)。
很多时候大家以C/C++接近机器底层(例如说,有指针的抽象,有手动分配内存),性能很高,来论证别的语言在这一点上不如C/C++(当然也确实有很多动态编程语言比不上,这要承认),要是一个语言没有指针,没有一个malloc的函数(或者别的各种各样的理由),就是不合机器底层的抽象。从本质上这就是在排挤别的编程语言的抽象。我就说说Haskell好了(我用Haskell举例就是想说明即使是Haskell这样的异端语言一样也有对同一个问题不同的处理方法),用malloc分配内存完全可以分配一个参数化类型的数组来代替呀(就是说把malloc包装在一个数组的类型构造器中,并且这个类型构造器是泛型的),在Haskell中一样指针的对应物,只不过它叫Ref(具体名字我记不得了,必须在一个IO Monad中使用,因为有副作用),当然你会争论这个指针不能用来做算术,只是一个引用,但是要做算术的指针应该使用前面所说的在数组上分配的内存块上做才有意义。
所以在大学阶段C/C++用的最多,大家最了解(非常深入的了解),懂的人多了自然话语权上就占有优势了,了解多了自然就可以说出一大堆好处,说出一大堆产品,反观其他编程语言(我说的是不是Python和Java这种),本来使用者就不多,自然势力就很小。我再用Haskell举例,大家总是吐槽Haskell是一个学术语言,没有实际用途,但是问题是很多人学Haskell的时候花的精力就不及C/C++多,所以了解就不深入,很多人知道的还是map,reduce之一套,但Haskell还有Monad和各种各样的语言扩展,涉及到很深的PL理论,而且Haskell一样有一本很厚的Reference book,对比大家学C/C++都看过几本书,有多少人学Haskell的时候看过几本书。而且有的人提到了写编译器,用Haskell来写的编译器也不少吧(不要争论Haskell底层是LLVM然后就和C++有关了,这毫无意义)不是非要把基础设施重写一遍才叫写了一个编译器。
我想说一下,大部分人认为的编程语言=C/C++ + Python+Java+Javascript,我认为的还额外包括Rust,Julia,Haskell,Prolog这些不入大流的编程语言。。。大家要看到这些小众编程语言,在资源非常有限的情况下还能作出了不少杰出的作品,在编程语言日益饱和的今天,这些语言能够活着就是很不容易的了,开发者精力是很有限的,不要觉得这世界上只有C/C++关心性能,很多这些开源编程语言作者也想提高程序的性能,但是很多时候有别的更加重要的事情要做,所以才搁置了(发明新的编程语言的目的,很大程度上是为了提供新的抽象,以及对固有模式进行优化,而非以用户完全手动控制为目的,所以提高编译器的能力(或者解释器)是所有编程语言的第一要务,C/C++性能来源的很大一部分,是编译器赐予的)。
所以总结一下,最重要的原因是:
1.C/C++是大家了解最多的编程语言,是教学时良好的“模型语言”,潜移默化的成为了标准,在这个领域大家也就不再发明有重复功能的语言了(除非有新的痛点要解决,比如说大家发明了Rust来解决内存问题)
2.很多工业设施都是用C/C++写的,所以没有动力更新
3.因为1,2,所以大家投入了更多的精力到C/C++中,由于马太效应,C/C++比别的语言更有优势。
大家一定要意识到,编程语言是一个有trade-off的事情,很多时候我们总是要牺牲掉一些东西换另外一些东西。就以异常处理为例,常见有三种方法
1.返回一个不可能值(例如-1),但是没有自己的类型
2.返回一个错误值(Error Code),可以有自己的类型(Maybe monad也在此列)
3.自己抛出一个错误打断程序
这三种方法一个比一个安全,但是一个比一个代价大,而且一旦选择一种就不能随便改动(虽然一个编程语言从能力上说3种可以支持,但是一般只有一种会成为主流的方法,就是说一种最佳实践)。谁不想要性能?但是在安全面前大家也要权衡一番,所以根据不同的应用大家采用了不同的设施,很多语言采用了3,追求部分性能的语言用了2,还有一些语言(如C语言)用了1。所以每个编程语言都是对某个特定问题的一个特定解决方案,没必要因为某个短板就互相看不起。
APSchmidt
发表于 2021-3-23 12:21
我一个C++的铁粉都快弃坑了。发张图片以表忠心。以前爱用这图片,现在经常在想要不要弃疗了。
标准委员会都在鼓捣些什么鬼东西?98到13年,标准15年之间原地踏步,然后到了最近几年,又突然飞快地出标准,甚至上一个标准出的东西根本还没有得到市场反馈、工程应用,下一个标准竟然又给废除了。况且新增的全是些语法细节,对工程应用上的帮助微乎其微,已经2019年了,C++ 标准库里面连个 socket 都没有,你能相信吗。C++的语法细节还不够多,隐晦的东西还不够多吗?我看了 Effective Modern C++里面,光是 auto + decltype 就说了 47 页,我只能说那些说用 auto 用得爽的人,恐怕没几个能完全明白自己写的 auto 到底推导出来是个啥类型。其实可怕的还不是能不能明白,而是 auto 这种东西其实就是在鼓励程序员根本不用去搞明白。
C++11要出来的时候,大家喊的是王者归来。从语言角度看确实王者无疑,但是标准库是彻底的青铜。Java、C#在语言层面未必比C++优秀到哪里去,但是人家的标准库是军火级别的,可以直接拉出来打仗。2019了C++标准库还只能写控制台黑窗口的学生成绩管理系统。确实C++的第三方库很多,但是各个库的框架、风格大相径庭,冗余严重,从工程集成和心理接受的角度都有负担。举个string的例子,标准库有个string、stingview,mfc有cstring,qt有qstring、qconststring,webkit有4-5种string,分别来自cf、wtf、webcore、webkit,wxwidgets有string,folly有string,com有bstr、ccombstr、_bstr_t,一个复杂的工程光是处理这些string就要多处不少事,问题就出在:标准库库太弱。Java、C#应该不需要操心这么多string的事吧。
总结一下:
1. C++语法太复杂,语言机制已经够牛B,门槛已经非常高,要熟练掌握的成本已经非常高了,然而新标准还在飞速地往更复杂的方向推进。
2. 标准库太弱,要在现实当中做项目,得依赖很多的第三方库,或者得自己撸,要自己做这些库的构建集成、兼容,多出来很多业务之外的成本。然而标准库的补充差不多10年踏一步。
一个项目,几个Java、C#初级程序员不服就是干,代码一把梭,分分钟项目上线了,C++这边的精英老手可能还在编译第三方库的1000行的模板错误提示里焦头烂额。
我曾经沉浸在C++语言的强大中,痴迷于模板元编程、预处理元编程的神奇,谁说C++不好就去杠谁。但是工作多年后,等那些奇巧淫技的新鲜感殆尽,如今只剩下稳扎稳打做项目的云淡风轻,可以说现在对它的看法是更现实、更客观的。
现在我只觉得标准委员在把 C++搞废的路上越走越远,无论是语言设计、工程实践上都比 C++优秀的语言在出现,rust/go 在PC、Server领域快速崛起,oc、swift、java、kotlin这些在移动端几乎占有了全部市场,甚至连浏览器内核这种铁打的地盘都快被人抢走了。C++在落后,无论是语言本身的进化还是市场占有率,已经在淘汰的过程中。
fwalker
发表于 2021-3-23 12:21
举个比较恰当的类比:现在的自动挡汽车越来越多,为什么手动挡还没被现在的时代淘汰呢?同理。