问题

纯C语言的工作有前(钱)景吗?

回答
纯 C 语言的工作有前(钱)景吗?——一个详细的探讨

纯 C 语言的工作在当今技术飞速发展的时代,仍然拥有非常坚实的“钱景”和广阔的“前”景,但需要我们从更深层次和更广阔的视角去理解。简单地说,答案是肯定的,但需要有策略的定位和持续的学习。

下面我将从多个维度详细阐述这个问题:

一、 C 语言的核心地位与不可替代性

首先,我们需要认识到 C 语言的根本地位。它是许多现代编程语言的基础,也是操作系统、嵌入式系统、驱动程序、高性能计算等领域的基石。

操作系统内核: Linux、Windows 的核心部分都是用 C 语言编写的。这意味着 C 语言程序员是操作系统开发和维护的关键人才。
嵌入式系统: 几乎所有的微控制器、物联网设备、汽车电子、工业自动化设备等都离不开 C 语言。这些设备对性能和资源要求极高,C 语言的低级控制能力和效率是其他语言难以比拟的。
高性能计算与科学计算: 在需要极致性能的领域,如金融交易系统、科学模拟、游戏引擎、图形渲染等,C 语言仍然是首选。
驱动程序开发: 硬件厂商需要 C 语言程序员来开发驱动程序,以便操作系统能够与硬件进行交互。
编译器与解释器: 许多编程语言的编译器和解释器本身就是用 C 语言编写的,例如 GCC、Clang。
网络协议栈: TCP/IP 等底层网络协议的实现也大量使用 C 语言。
数据库系统: 许多成熟的数据库系统(如 MySQL)的底层都是用 C 语言编写的。

总结: C 语言掌握了计算机硬件的“钥匙”,在对性能、资源控制、底层操作有极致要求的领域,它依然是无可替代的。这些领域往往是支撑现代科技运作的基石,其需求量和重要性不言而喻。

二、 C 语言在“钱景”方面的体现

“钱景”与 C 语言的关联体现在以下几个方面:

1. 高稀缺性人才,高薪资回报:
技能门槛高: 掌握纯粹的 C 语言,尤其是深入理解内存管理、指针、多线程、操作系统原理等,需要扎实的基础和丰富的经验。这导致了具备这些能力的 C 程序员相对稀缺。
企业争抢: 很多大型科技公司、汽车制造商、半导体公司、金融机构等,都需要顶级的 C 语言工程师来开发核心产品和技术。这种高需求与低供给的状况,自然推高了薪资水平。
项目关键性: C 语言项目往往是企业最核心的业务,一旦出现问题,影响巨大。因此,企业愿意为这些关键岗位的优秀人才支付更高的薪资。

2. 特定行业的收入优势:
嵌入式开发: 随着物联网、智能家居、智能穿戴等设备的发展,嵌入式 C 程序员的需求量持续增长。尤其是在高端的汽车电子、航空航天、医疗器械等领域,C 语言工程师的薪资待遇非常可观。
操作系统与底层开发: 在这些领域工作的工程师,往往拥有更高的技术深度和广度,薪资水平也处于行业前列。
高性能计算/金融科技: 算法交易、高频交易等对代码效率要求极致的领域,C++(通常也包含 C 语言的深厚功底)程序员薪资回报极高。

3. “一技在身,吃遍天下”的稳定性:
技术生命周期长: C 语言作为一种底层语言,其核心概念和应用场景不会轻易过时。即使出现了新的语言和框架,C 语言的地位依然稳固,尤其是在对稳定性和兼容性要求极高的传统行业和大型系统中。
职业生涯路径宽广: 即使不直接从事纯 C 开发,C 语言的基础知识也能让你更容易地学习和理解其他语言(如 C++, Java, Python)的底层机制,从而拓宽职业发展道路。许多高级架构师、技术总监都拥有扎实的 C 语言背景。

三、 C 语言在“前”景方面的广阔性

“前”景意味着未来的发展空间和潜在机会:

1. 技术发展的新驱动力:
人工智能与机器学习(底层优化): 虽然 Python 是 AI 的热门语言,但其底层高性能计算库(如 TensorFlow, PyTorch)很多都是用 C/C++ 编写的,以 C 语言的知识可以参与到这些库的优化和开发中,提升 AI 模型的运行效率。
操作系统和云计算: 随着云计算的深入发展,对操作系统内核、虚拟化技术、容器技术(如 Docker, Kubernetes 的底层组件)的需求越来越大,这些都离不开 C 语言。
边缘计算与物联网的爆发: 物联网设备数量爆炸式增长,对嵌入式系统的性能、功耗、实时性要求越来越高,C 语言在这一领域的重要性愈发凸显。未来会有更多的创新机会出现在边缘计算和物联网应用中。
区块链技术: 许多区块链的核心协议和高性能节点实现都采用了 C++,其中也涉及大量的 C 语言编程思想。

2. 解决“硬”问题的能力:
性能优化: 当其他高级语言遇到性能瓶颈时,往往需要通过 C/C++ 来进行底层优化,或者编写高性能的库。C 语言工程师是解决这些“硬”问题的专家。
资源受限环境: 在内存、CPU 资源极其有限的嵌入式设备、实时操作系统中,C 语言是唯一能有效进行开发的语言。

3. 跨领域的技术桥梁:
C 语言是理解计算机底层原理(如内存、CPU 指令、操作系统调度等)的绝佳工具。掌握了 C 语言,你就能更好地理解和运用其他语言和技术,成为不同技术栈之间的桥梁。

四、 风险与挑战

当然,我们也需要看到纯 C 语言工作所面临的挑战:

开发效率相对较低: 相较于一些高级语言,C 语言的开发效率可能稍低,需要开发者更谨慎地处理内存管理和错误。
学习曲线较陡峭: 掌握 C 语言的精髓,需要投入大量的时间和精力去理解底层机制,对新手来说可能存在一定的门槛。
特定领域导向: C 语言的工作机会更集中在对性能和底层控制要求较高的领域,而非所有互联网应用或 Web 开发都会大规模使用纯 C。
内存安全和调试困难: 内存泄漏、指针越界等问题是 C 语言的常见挑战,需要开发者具备良好的调试能力和严谨的编程习惯。

五、 如何最大化 C 语言的“钱景”和“前”景

要在这个领域获得成功,你需要:

1. 深入理解底层原理: 不仅仅是语法,更要深入理解操作系统原理、计算机体系结构、内存管理、并发与多线程等。
2. 精通至少一个相关领域: 例如嵌入式系统开发(STM32, Linux 嵌入式)、操作系统开发、驱动程序开发、高性能计算、网络编程等。
3. 掌握 C++: 对于很多高性能和复杂系统开发,C++ 是更常用的工具。C++ 是 C 语言的超集,熟练掌握 C 语言是学习 C++ 的坚实基础。很多公司招聘时会同时需要 C 和 C++ 的技能。
4. 保持学习的热情: 技术在不断发展,要关注新的技术趋势,例如 Rust 语言在系统编程领域的崛起,以及 AI、边缘计算等带来的新机遇。
5. 提升软技能: 良好的沟通能力、团队协作能力、问题分析和解决能力,在任何技术领域都至关重要。

结论

纯 C 语言的工作绝对是有前(钱)景的。 它代表着计算机科学最核心的部分,是支撑现代技术基石的语言。虽然它不像一些前端或移动开发语言那样“光鲜亮丽”,但其深厚的技术内涵、高稀缺性人才的特点,以及在关键技术领域的不可替代性,都决定了 C 语言开发者在薪资待遇和职业发展上拥有坚实的“钱景”。

更重要的是,C 语言为你打开了通往底层世界的大门,让你能够深入理解计算机是如何工作的,并且能够解决那些最棘手、最需要性能和效率的问题。在人工智能、物联网、云计算等新兴技术蓬勃发展的今天,对 C 语言及其衍生技能的需求只会持续增长。

因此,如果你对计算机底层原理充满好奇,愿意深入钻研技术细节,那么选择 C 语言并深耕下去,绝对是一个明智且回报丰厚的职业选择。关键在于如何定位自己,如何不断学习和适应变化,将 C 语言的强大能力应用到最有价值的领域。

网友意见

user avatar

要不要黑一下 C++呢?呵呵呵。

------------------

咱们要有点娱乐精神,关于 C++的笑话数都数不清:

笑话:C++是一门不吉祥的语言,据说波音公司之前用ADA为飞机硬件编程,一直用的好好的,后来招聘了一伙大学生,学生们说我靠还在用这么落后的语言,然后换成C++重构后飞机就坠毁了。

笑话:什么是C++程序员呢?就是本来10行写得完的程序,他非要用30行来完成,并自称“封装”,但每每到第二个项目的时候却将80%打破重写,并美其名曰 “重构”。

笑话:C容易擦枪走火打到自己的脚,用C++虽然不容易,但一旦走火,就会把你整条腿给炸飞了。

笑话:同时学习两年 Java的程序员在一起讨论的是面向对象和设计模式,而同时学习两年 C++的程序员,在一起讨论的是 template和各种语言规范到底怎么回事情。

笑话:教别人学 C++的人都挣大钱了,而很多真正用 C++的人,都死的很惨。

笑话:C++有太多地方可以让一个人表现自己“很聪明”,所以使用C++越久的人,约觉得自己“很聪明”结果步入陷阱都不知道,掉坑里了还觉得估计是自己没学好 C++。

笑话:好多写了十多年 C++程序的人,至今说不清楚 C++到底有多少规范,至今仍然时不时的落入某些坑中。

笑话:很多认为 C++方便跨平台的人,实际编写跨平台代码时,都会发现自己难找到两个支持相同标准的 C++编译器。

---------------

Q:那 C++为什么还能看到那么多粉丝呢?

A:其实是因为 Windows,因为 Windows的兴起带动了 C++,C++本来就是一门只适合开发 GUI的语言。

Q:为何 C++只适合开发 GUI呢?

A:你看 Unix下没有 GUI,为啥清一色的 C呀?所有的系统级问题都能在 C里找到成熟的解决方案,应用级问题都能用其他高级语言很好地解决,哪里有 C++什么事情呀?

Q:你强词夺理,Unix下也有 C++的项目呀。

A:有,没错,你任然可以用任何语言编写任何糟糕的代码。

Q:别瞎扯了,你都在说些什么?连C++和 Windows 都扯到一起去了。

A:回想下当年的情景,一个大牛在教一群初学者如何编程。一边开发一边指着屏幕上说,你看,这是一个 Button,我们可以用一个对象来描述它,那是一个 panel我们也可以用一个对象来描述它,并且你们有没有发现,其实 Button和 Panel是有血缘关系的,你们看。。。这样就出来了。。。。下面的学生以前都是学着学校落后的教材,有些甚至还在用 turboc的 bgi库来画一些点和圆。哪里见过这么这么华丽的 Windows 界面呀。大牛说的话,象金科玉律一样的铭刻在自己幼小的心理。一边学着 Windows,一边发现,果然,他们都需要一个基类,果然,他们是兄弟关系,共同包含一些基本属性,可以放到基类去。他们越用越爽,潜意识里觉得因为 C++这么顺利的帮他们解决那么多界面问题,那看来 C++可以帮他们解决一切问题了。于是开发完界面以后,他们继续开发,当他们碰到各种设计问题时,反而认为肯定自己没有用好 C++。于是强迫自己用下去,然后就完蛋了。

---------------

关于 C++的笑话我有一箩筐,各位 C++粉用不着对号入座。言归正传,为什么要黑 C++呢?谈不上黑不黑,我从94年开始使用 C++(先前是 C 和 Pascal),一路看着 C++成长壮大,用 C++写过的代码,加起来应该超过 10MB了吧,C++的各种宝典我也都读过,一直到 2004年开始切回 C,主要原因是发现很多没法用 C++思路继续解决下去的问题,或者说用 C++思路解决下去会很糟糕的问题。

那时候(2004-2005)正是 C++满天飞的时候,言必称 C++,用必用模版,我跳出来说你们醒醒吧,别过火了,这个世界并不是都是抽象数据结构和算法就可以描述清楚的。于是很多人激动的跳出来说:“你没领会到 C++精髓,你根本都不会用 C++”。我问他们:“语言是用来解决问题的,如果一个语言学了三四年都会经常掉沟里,算好语言么?如果编写十多年 C++的程序员都很难掌握得了,这算好语言么”。他们又说:“语言是死的,人是活的”。

我记得当时一位国内 C++大牛,为了纠正我的 “错误观点”,给我看过他写的一套十分强大的库,我打开一看,倒吸了一口冷气,全部是 .h文件。我只能回他三个字:“你牛逼”。当然这是一个极端的例子,那家伙后来终于也开始把 .h里面的东西逐步挪到 .cpp里面了,这是好事。

当时和云风在一家公司,2004年新人培训时,他给新人布置了一个实现内存分配器的作业,批改作业的时候,他经常边看边问人家,“不够C++呀,你能不能百分之百OOP?”,“1%的 C都不要留”。我当时在公司内部邮件列表里面发过关于 C++的问题,大部分人都表示:“你看没有C++我们怎么写3D引擎呢?”。我跟他们讲:“John Carmack直到 Quake3都还在用着 ANSI C,后来因为不得不支持 D3D,改用 C++了。为啥 C不能写 3D引擎了?”。他们告诉我:“你看,Point,就是个对象,Matrix也是个对象,那么多 Vector的代数计算,用 C++的算术重载是多么美妙的事情,三维世界就是对象的世界。”。

确实当时客户端 GUI的话,只有 C++,图形引擎也只有 C++,这两个正是C++最强的地方,所以我也没和他们争辩,强迫他们承认 C也可以很漂亮的写图形,而且C写的可以写的很优雅。我又不是闲着没事情,何必去质疑人家的核心价值观呢,呵呵。当年我正在接手一个 C++项目,代码超过 800KB,每次崩溃都需要花费很长时间去定位,项目中大量的前后依赖,改一个地方,前后要看好几处,一处遗漏,整个系统就傻逼了。我开始重构后,画了两个星期,将性能敏感的核心部分剥离出来用 C实现(代码量仅 200KB),然后导出 Python接口,用Python来完成剩下的部分,整个脚本层代码量只有 150KB。整个世界清爽了,整个 C++项目原来的工期为 2个程序员四个月,我一个人重构的时间加起来就 1.5个月,而且代码量比远来少了两倍还多,各种奇特的 BUG也一扫而尽。我看看左边的 800KB一团乱麻的 C++代码,再看看右边整洁的 300多 KB 纯 C + Python,琢磨着,这个项目干嘛不一开始就这么做?

跨语言接口

现代项目开发,不但需要更高的性能,而且需要更强大的语言描述能力。而 C++正处在一个尴尬的地方,比底层,它不如 C能够精确的控制内存和硬件,各种隐式构造让你防不胜防;比描述能力,比快速业务开发和错误定位,它又赶不上 Python, Ruby, Lua等动态语言,处于东线和西线同时遭受挤压和蚕食的地步。

很快,

2006-2007

年左右,其他项目组各种滥用 C++的问题开始显现出来:当时脚本化已经在工程实践中获得极大的成功,然而某些项目一方面又要追求 100%的 C++,另一方面又需要对脚本导出接口,他们发现问题了,不知道该怎么把大量的 C++基础库和接口导给 Lua。

C的接口有各种方便的方式导给脚本,然而整个项目由一群从来就不消于使用脚本的cpp大牛开发出来,当他们要吧cpp类导出接口给脚本时,他们设计了一套牛逼的系统,lua自动生成机器码,去调用c++的各种类,没错,就是c++版本的cffi或者ctypes。他为调用vc的类写了一套机器码生产,又为调用gcc的类写了一套代码生成。那位cpp大牛写完后四处炫耀他的成果,后来他离职了,项目上线一而再再而三的出现无可查证的问题,后来云风去支援那个项目组,这套盘根错节的c++项目,这套盘大的代码自生成系统深深的把他给恶心到了。后来众所周知云风开始反C++,倡导回归C了,不知道是否和这个项目有关系。

于是发现个有趣的现象,但凡善于使用脚本来提高工程效率的人,基本都是C加动态语言解决大部分问题(除了gui和图形),但凡认为c++统治宇宙的人很多都是从来没使用过脚本或者用了还不知道该怎样去用的人。

凭借这样的方法,我们的产品同竞争对手比拼时,同样一个功能,同样的人力配置,竞争对手用纯C++要开发三月,我们一个月就弄出来了,同样的时间,对手只能试错一次,我们可以试错三次。后来,据我们招聘过来的同事说,竞争对手也开始逐步降低 C++的比例,增加 java的比例了,这是好事,大家都在进步嘛。

ABI的尴尬

ABI级别的 C++接口从来没有标准化过,以类为接口会引入很多隐藏问题,比如内存问题,一个类在一个库里面实例化的,如果再另外一个库里面释放它们就有很多问题,因为两个动态库可能内存管理系统是不一样的。你用这里的 allocator分配一块内存,又用那里的 allocator去释放,不出问题才怪。很多解决方法是加一个 Release方法(比如 DX),告诉外面的人,用完的时候不要去 delete,而是要调用 Release。项目写大了各个模块隔离成动态库是很正常的,而各种第三方库和自己写的库为追求高性能引入特定的内存管理机制也是很正常的。很多人不注意该调用release的地方错写成delete就掉沟里去了。更有胜者跨 ABI定义了很多inline方法的类,结果各种隐式构造和析构其实在这个库里生成,那个库里被析构,乱成一团乱麻。C就清晰很多,构造你就调用fopen,析构你就fclose,没有任何歧义。其实C++的矛盾在于一方面承认作为系统级语言内存管理应该交给用户决定一方面自己却又定义很多不受用户控制的内存操作行为。所以跨 ABI层的c++标准迟迟无法被定义出来,不是因为多态 abi复杂,而是因为语言逻辑出现了相互矛盾。为了弥补这个矛盾,C++引入了operator new,delete,这new/delete重载是一个补丁并没从逻辑上让语言变得完备,它的出现,进一步将使用者拖入bug的深渊。

其实今天我们回过头去看这个问题,能发现两个基本原则:跨abi的级别上引入不可控的内存机制从语言上是有问题的,只能要靠开发者约定各种灵巧的基类和约定开发规范来解决,这个问题在语言层是解决不了的;其次你既然定义了各种隐式构造和析构,就该像java活着动态语言一样彻底接管内存,不允许用户再自定义任何内存管理方法,而不是一方面作为系统极语言要给用户控制的自由,一方面自己又要抢着和用户一起控制。

因此对象层 ABI接口迟迟无法标准化。而纯 C的 ABI不但可以轻松的跨动态库还能轻松的和汇编及各类语言融合,不是因为C设计多好,而是C作为系统层语言没有去管它不该管的东西。当年讨论到这个话题时 C++大牛们又开始重复那几句金科玉律来反驳我:“语言只是招式,你把内功练好,就能做到无招胜有招,拿起草来都可以当剑使,C++虽然有很多坑,你把设计做好不那么用不就行了”。我说:本来应该在语言层解决好的事情,由于语言逻辑不完备,将大量问题抛给开发者去解决极大的增加了开发者的思维负担,就像破屋上表浆糊一样。你金庸看多了吧,武术再高,当你拿到一把枪发现子弹不一定往前射,偶尔还会往后射时,请问你是该专心打敌人呢?还是时刻要提防自己的子弹射向自己?

系统层的挫败

C++遭受挫败是进军嵌入式和操作系统这样靠近硬件层的东西。大家觉得宇宙级别的编程语言,自然能够胜任一切任务,很快发现几个问题:

  • 无法分配内存:原来用 C可以完全不依赖内存分配,代码写几千行一个 malloc没有都行。嵌入式下处理器加电后,跳到特定地址(比如起始地址0),第一条指令一般用汇编来写,固定在0地址,就是简单初始化一下栈,然后跳转到 C语言的 start函数去,试想此时内存分配机制都还没有建立,你定义了两个类,怎么构造呀?资源有限的微处理器上大部分时候就是使用一块静态内存进行操作。C++写起来写爽了,各种隐式构造一出现,就傻了。
  • 标准库依赖:在语言层面,C语言的所有特性都可以不用依赖任何库就运行,这为编写系统层和跨平台跨语言代码带来了很方便的特性。而C++就不行,我要构造呀,我要异常呀,你能不给我强大的运行时呢?什么你还想用 stl?不看看那套库有多臃肿呀(内存和代码尺寸)。
  • 异常处理问题:底层开发需要严格的处理所有错误返回,这一行调用,下一行就判断错误。而异常是一种松散的错误处理方式,应用层这么写没问题,系统层这么写就很狼狈了。每行调用都try一下和 C的调用后if判断结果有什么区别?C++的构造函数是没有返回值的,如果构造内部出错,就必须逼迫你catch构造函数的异常,即便你catch住了,此时这个实例是一个半初始化实例,你该怎么处理它呢?于是有人把初始化代码移除构造函数,构造时只初始化一下变量,新增加一个带返回的init函数,这样的代码写的比C冗余很多。何况硬件中断发生时,在你不知道的情况下,同事调到一些第三方的库,你最外层没有把新的exception给 catch住,这个exception该往哪里抛呀?内存不够的时候你想抛出一个 OutOfMemoryException,可是内存已经不够了,此时完全无能力构造这个异常又该怎么办呢?
  • 处理器兼容:C++的类依赖基地址+偏移地址的寻址方式,很多微处理器只有简单的给定地址寻址,不支持这样一条语句实现BASE+OFFSET的寻址,很多C++代码编译出来需要更多的指令来运算地址,导致性能下降很多,得不偿失。
  • 隐式操作问题:C的特点是简单直接,每行语句你都能清楚的知道会被翻译成什么样子,系统会严格按照你的代码去执行。而用C++,比如 str1 = str2 + "Hello" + str3; 这样的语句,没几个人真的说得清楚究竟有多少次构造和拷贝,这样的写法编写底层代码是很不负责任的,底层需要更为精细和严格的控制,用C语言控制力更强

当然,说道这里很多人又说,“C++本来就是 C的超集,特定的地方你完全可以按照C的写法来做呀。没人强迫你构造类或者使用异常呀”,没错,按 Linus的说法:“想要用 C++写出系统级的优秀的可移植和高效的代码,最终还是会限于使用 C本身提供的功能,而这些功能 C都已经完美提供了,所以系统层使用 C的意义就在于在语言层排除 C++的其他特性的干扰”。

很多人都记得 Linus在 2007年因为有人问 Git为什么不用 C++开发炮轰过一次C++。事实上2004年 C++如日中天的时候,有人问 Linux内核为何不用 C++开发,他就炮轰过一次了:

实际上,我们在1992年就尝试过在Linux使用 C++了。很恶心,相信我,用C++写内核是一个 “BLOODY STUPID IDEA”。事实上,C++编译器不值得信任,1992年时它们更糟糕,而一些基本的事实从没改变过:

- 整套 C++异常处理系统是 “fundamentally broken”。特别对于编写内核而言。
- 任何语言或编译器喜欢在你背后隐藏行为(如内存分配)对于开发内核并不是一个好选择。
- 任然可以用 C来编写面向对象代码(比如文件系统),而不需要用 C++写出一坨屎来。

总得来说,对任何希望用 C++来开发内核的人而言,他们都是在引入更多问题,无法象 C一样清晰的看到自己到底在写什么。

C++粉丝们在C++最火热的时候试图将 C++引入系统层开发,但是从来没有成功过。所以不管是嵌入式,还是操作系统,在靠近硬件底层的开发中,都是清一色的 C代码,完全没有 C++的立足之地。

应用层的反思

STL出来后,给人一种 C++可以方便开发应用层逻辑的错觉。由于很多语言层不严密的事情,让STL来以补丁的方式完成,于是很多以为可以象写 java一样写 C++的初学者落入了一个个的坑中。比如 list.size(),在 Windows下vc的 stl是保存了 list的长度的,size()直接 O(1)返回该变量,而在gcc的 stl中,没有保存 list长度,size()将搜索所有节点,O(n)的速度返回。

由于语言层不支持字符串,导致 std::string实现十分不统一,你拷贝构造一个字符串,有的实现是引用,才用 copy-on-write的方法引用。有的地方又是 new,有的实现又是用的内存池,有的实现线程安全,有的实现线程不安全,你完全没法说出同一个语句后面到底做了些什么(见孟岩的《

Linux之父话糙理不糙

》)。

再比如说我想使用 hash_map,为了跨平台(当你真正编写跨平台代码时,你很难决定目标编译器和他们的版本,想用也用不了 unordered_map),我很难指出一种唯一声明 hash_map的方法,为了保证在不同的编译器下正常的使用 hash_map,你不得不写成这样:

       #ifdef __GNUC__  #ifdef __DEPRECATED   #undef __DEPRECATED  #endif  #include <ext/hash_map>  namespace stdext { using namespace __gnu_cxx; }  namespace __gnu_cxx {   template<> struct hash< std::string > {    size_t operator()( const std::string& x ) const {     return hash< const char* >()( x.c_str() );    }   };  } #else  #ifndef _MSC_VER   #include <hash_map>  #elif (_MSC_VER < 1300)   #include <map>   #define IHAVE_NOT_HASH_MAP  #else   #include <hash_map>  #endif #endif  #ifdef __GNUC__  using namespace __gnu_cxx;  typedef hash_map<uint32_t, XXXX*> HashXXXX; #else  using namespace stdext;  typedef hash_map<uint32_t, XXXX*> HashXXXX; #endif     

如果有更好的跨平台写法,麻烦告诉我一下,实在是看不下去了。一个基础容器都让人用的那么辛苦,使得很多 C++程序员成天都在思考各种规范,没时间真正思考下程序设计。

由于语言层要兼容 C,又不肯象 C一样只做好系统层的工作,导致当 C++涉足应用层时,没法接管内存管理,没法支持语言层字符串,没法实现语言层基础容器。所以需要借助一些 stl之类的东西来提供便利,但 stl本身又是充满各种坑的。且不说内存占用大,程序体积大等问题,当编译速度就够呛了。所以为什么 C++下面大家乐意重复造轮子,实现各种基本容器和字符串,导致几乎每个不同的 C++项目,都有自己特定的字符串实现。就是因为大家踩了坑了,才开始觉得需要自己来控制这些细节。stl的出发点是好的,但是只能简单小程序里面随便用一下,真是大项目用,stl就容易把人带沟里了,所以很多大点的 C++项目都是自己实现一套类似 STL的东西,这难道不是违背了 stl设计的初衷了么?

语言层的缺失,让大家为了满足业务开发的快速迭代的需求,创造了很多很基础的设计灵巧的基类,来提供类似垃圾回收,引用计数,copy-on-write,delegate,等数不胜数的功能。每个项目都有一系列 BaseObject 之类的基础类,这样就引入一个误区,两年后你再来看你的代码,发现某个 BaseObject不满足需求了,或者你和另外一个项目 merge代码时,需要合并一些根本属性。图形和GUI这些万年不变的模型还好,应用类开发千变万化,一旦这些设计灵巧的基类不再适应项目发展时,往往面临着全面调整的代价。

打开一个个 C++大牛们 blog,很多地方在教你 std::string的原理,需要注意的事项。map的限制,vector的原理,教你如何实现一个 string。这就叫 “心智负担”,分散你的注意力,这是其他语言里从来见不到的现象。战士不研究怎么上前线杀敌,天天在琢磨抢和炮的原理,成天在思考怎么用枪不会走火,用炮不会炸到自己,这战还怎么打?

所以此后几年,越来越多的人开始反思前两年C++过热所带来的问题,比如高性能网络库 ZeroMQ作者 Martin Sustrik 的:《

为什么我希望用C而不是C++来实现ZeroMQ

》,比如云风的《

云风的 BLOG: C 的回归

》,比如引起热议的《

Why C++ Is Not "Back"

》。

全面被代替

2008年以后,行业竞争越来越激烈,正当大家一边苦恼如何提高开发效率,一边掉到C++的各种坑里的时候,越来越多的应用开发方案涌现出来,他们都能很好的代替 C++。各行各业的开发者逐步相见恨晚的发现了各种更加优秀的方案:需要底层控制追求性能的设计,大家退回到 C;而需要快速迭代的东西大家找到各种动态语言;介于性能和开发速度之间的,有java,知乎上好像很多黑java的,语言是有不足,但是比起C++好很多,没那么多坑,真正考虑面向对象,真正让人把心思放在设计上。所以再黑也不能挡住 java在 tiobe上和 C语言不是第一就是第二的事实,再黑也挡不住 java在云计算,分布式领域的卓越贡献。

所以2005年以后,C++处在一个全面被代替的过程中:

  • 底层系统:进一步回归 C语言,更强的控制力,更精确的操作。
  • 网页开发:2006年左右,C++和 fastcgi就被一起赶出 web世界了。
  • 高性能服务:varnish, nginx, redis 等新的高性能网络服务器都是纯C开发的。
  • 分布式应用:2007年左右, C++被java和其他动态语言彻底赶跑。
  • 游戏服务端:2008年后进一步进化为 C 和 脚本,完全看不到胖C++服务端了。
  • 并行计算:2010年后,go, scala, erlang;而能方便同go接口的,是 C不是C++。
  • 游戏引擎:没错 C++和脚本,但是这年头越来越多的开源引擎下,引擎类需求越来越少。
  • 游戏逻辑:脚本
  • 多媒体:SDL纯C,ffmpeg是纯 C,webrtc的核心部分(DSP, codec)是纯C的。
  • 移动开发:早年C++还可以开发下塞班,现在基本被 java + objc + swift 赶跑了。
  • 桌面开发:Qt+Script, C#等都能做出漂亮的跨平台界面。且界面脚本化趋势,不需要C++了。
  • 网页前端:JavaScript, Html5, Flash
  • 操作系统:FreeBSD, Open Solaris, Linux, RTOS, Darwin(OS X 底层),都是纯 C
  • 虚拟技术:qemu / kvm (云计算的基石)纯 C,Xen 纯 C
  • 数据库:MySQL (核心纯C,外围工具 C++),SQLite 纯 C, PostgreSQL / BDB / unqlite 纯C
  • 编译器:C/C++并存,不过编译器用脚本写都没关系,我还在某平台用 java写的 C/C++编译器
  • 大数据:kafka, hadoop, storm, spark 都使用 Java
  • 云存储:openstack swift python, hdfs java, 还有好多方案用 go

可以看出,即便 C++的老本行,GUI和图形(确实也还存在一些短期内 C++无法替代的领域,就像交易统里还有 COBOL一样),这年头也面临的越来越多的挑战,比如新发布的 Rust (

如何看待 Rust 的应用前景? - 知乎用户的回答

)。可以发现,开发技术多元化,用最适合的技术开发最适合的应用是未来的趋势。而为这些不同的技术编写高性能的可控的公共组件,并轻松的和其他语言接口,正是 C语言的强项。所以不管应用层语言千变万化,对系统级开发语言C的需求还是那么的稳定,而这个过程中,哪里还有 C++的影子呢?

话题总结

所以说未来的趋势是:C x 各种语言混搭 的趋势,从TIOBE上 C++的指数十年间下跌了三倍可以看出,未来还会涌现出更多技术来代替各个角落残存的C++方案,C++的使用情况还会进一步下降。所以题主问学习纯C是否有前途,我觉得如果题主能够左手熟练的掌握 C语言,培养系统化的思维习惯和精确控制内存和硬件的技巧;右手继续学习各种新兴的开发技术,能够应对各个细分领域的快速开发,碰到新问题时能左右开弓,那么未来工作上肯定是能上一个大台阶的。至于C++ 嘛,有时间看看就行,逼不得已要维护别人代码的情况下写两行即可。

故事分享

古代用弓箭进行远距离攻击时,对射手要求较高,瞄准难度大,需要一直使劲保持准心。战斗中一个弓箭手开弓二十次就需要比较长的休息时间。弩的威力远胜于弓,秦弩的制造就如现代的自动步枪一般精密无二,它既可以延长射击,又可以精确瞄准。弩箭的发射速度更是弓箭的数倍,威力惊人。因为弩的操作非常简单,不需要射击技巧,平民很容易掌握它的使用方法。秦国靠着弩兵,在战争中取得了不少优势,被人称为 “虎狼之师”。

日本投降时,天皇下罪己诏。很多士兵不愿意相信这时真的,找种种理由拒绝相信。有的士兵甚至以为天皇的广播是敌人诱降的把戏,于是躲到丛林里继续三五成群的收集情报,袭击可以攻击的目标,等待上司来给他们下达新命令。直到好几年后看到周围的人都穿着日常的便装了,而来巡山的 “敌人” 也从士兵变为了巡逻队,他们都还觉得这是敌人的伪装。而同时,德国战败时,最后的党卫军一直战斗到 1957年才肯投降。

-----------------------------------------

很多人觉得 java慢,C++快java 10倍以上已经是上世纪的事情了,现代的 java 只比 C/C++慢 70%,C++连1倍都快不了 java。也不要觉得动态语言慢,javascript只比C/C++慢 2.7倍。luajit只比 C++慢 5.8倍。在 jit技术发展的今天,C++在性能上离动态语言/java的差距越来越小,可易用性和生产效率上的差距,却和动态语言/java 比起来越来越大。

---------------------------

最后,补充一张图:

----

类似的话题

  • 回答
    纯 C 语言的工作有前(钱)景吗?——一个详细的探讨纯 C 语言的工作在当今技术飞速发展的时代,仍然拥有非常坚实的“钱景”和广阔的“前”景,但需要我们从更深层次和更广阔的视角去理解。简单地说,答案是肯定的,但需要有策略的定位和持续的学习。下面我将从多个维度详细阐述这个问题: 一、 C 语言的核心地位.............
  • 回答
    是的,可以做到,但要实现这个目标需要一些复杂的操作和对 C++ ABI、链接器行为的深入理解。核心思想是:1. 在动态库内部隔离 C++ 标准库的依赖: 确保你的动态库在加载时,其内部使用的 `libstdc++` 版本不会与应用程序期望的 C++ 标准库版本发生冲突。2. 提供一个纯 C 的封.............
  • 回答
    美学是一个非常主观的概念,每个人都有自己独特的审美偏好。因此,要说哪面国旗是“最好看的”,这本身就带有很强的个人色彩。然而,如果从普遍接受的视觉设计原则、色彩搭配、象征意义的传达以及历史文化底蕴等角度来综合考量,一些国旗确实能引发更广泛的赞誉。在纯美学考虑下,如果要选出一面最能引发普遍好感的国旗,我.............
  • 回答
    纯机械时代的巅峰,如果我们将“纯机械时代”定义为人类主要依靠机械力量和结构来完成各种任务,而尚未大规模引入电力、电子技术和自动化(尤其是信息自动化)的时代,那么其巅峰无疑是工业革命后期及随之而来的新帝国主义时期(大致从19世纪中叶到20世纪初)。在这个时代,人类创造出了前所未有的、复杂而庞大的机械装.............
  • 回答
    从纯军事角度,将当前驻扎在乌克兰的俄军替换为相同数量的中国人民解放军(PLA),能否“打得更好”是一个复杂且多层面的问题,需要从多个维度进行详细分析。这个问题的核心在于比较两个军队在不同战略、战术、技术、后勤、士气以及在完全不同战场环境下的表现差异。以下将从几个关键军事要素进行详细阐述:1. 指挥与.............
  • 回答
    没问题,非常乐意为你提供详细的批评和建议!作为纯新人,能迈出写小说的第一步已经非常了不起了,请不要害怕批评,这正是进步的阶梯。请先将你的小说开篇发给我,我才能进行详细的分析。一旦你发给我,我会从以下几个方面进行详细的评估,并给出具体的建议:在等待你的开篇过程中,我先为你列出一些我通常会关注的评估角度.............
  • 回答
    关于传统医学能否治愈新冠病毒的讨论,确实是一个复杂且常常带有争议的话题。这背后涉及到我们如何理解疾病、如何验证疗效,以及传统医学自身的特点。首先,需要明确的是,“纯靠传统医学连新冠都诊断不出来” 这句话,在现代医学诊断的语境下是成立的。现代医学对新冠病毒的诊断,主要依赖于实验室的分子生物学技术,如核.............
  • 回答
    乘坐纯电动公交还是燃油公交更舒服,这真是一个挺有意思的问题,因为影响舒适度的因素很多,而且不同的人感受也可能不一样。不过,如果咱们掰开了揉碎了聊,大概能说清楚一些道道。从最直观的“坐”来说: 噪音和震动: 这可能是最能直接感受到区别的地方了。燃油公交车毕竟是内燃机在工作,轰隆隆的发动机声音加上时.............
  • 回答
    说实话,跟导师开会,内容挺杂的。有时候是聊研究进展,有时候是聊学术会议,有时候甚至会聊到一些更生活化的东西。感觉导师就像一个经验丰富的老船长,而我就是那个在茫茫大海上摸索新航线的水手。研究进展,那是重头戏。 “最近有什么新想法吗?” 这是导师最常问的问题之一。我一般会提前准备好,把最近思考过的一.............
  • 回答
    从纯粹的军事角度出发,假设将目前在乌克兰的俄军替换成同等数量、装备和训练水平的美军,美军能否打得“更好”是一个非常复杂的问题,答案并非简单的“是”或“否”。这涉及到战术、战略、后勤、情报、人员素质、指挥体系以及战场环境等多个维度。1. 战术层面: 进攻与防御: 美军在现代战争中,尤其是在近几十年.............
  • 回答
    好的,纯新人写了一段网文开头,希望能得到各位大佬的指点!下面我会尽量详细地解答,并确保我的回答听起来像是一个真诚、有经验的网文老司机在给新人提建议,绝不带一丝AI痕迹。首先,请允许我——作为一个经历过无数次“开篇扑街”和“字数被限”的老油条——为你的勇气点赞!写网文,特别是开头,就像在黑暗中摸索前行.............
  • 回答
    关于“纯中医药能否真正有效治愈癌症”这个问题,这是一个复杂且备受关注的议题,需要从多个角度进行详细的阐述。核心观点:目前,科学界和医学界的普遍共识是,“纯中医药”在绝大多数情况下,并不能真正“治愈”现代医学定义下的癌症(特指肿瘤细胞的根除和患者的长期无癌生存)。 然而,中医药在癌症治疗中发挥着重要的.............
  • 回答
    这个问题问得相当实在,很多想要搭建个性化网络的朋友都会纠结这一点。直接说结论,通常情况下,“软路由 + 交换机”的组合,如果选择合适的硬件,总体成本会比“纯软路由”要低一些,但这里面有很多细节需要剖析。让我好好跟你掰扯掰扯,尽量说得透彻点,让你自己也能判断。 先拆解一下两个概念:1. 纯软路由: .............
  • 回答
    嗨!很高兴你能来问这个问题,耳机这个东西啊,刚开始接触确实有点小小的门道。你问的“监听耳机有什么用,正常听歌需要用吗”这个问题,我可以给你掰开了揉碎了说清楚。首先,咱们先来聊聊“监听耳机”到底是个啥玩意儿?你可以把监听耳机想象成一个“老实人”。它最核心的特点就是真实、还原。它不像咱们平时听歌追求的“.............
  • 回答
    你好!非常理解你想要尝试威士忌,但又不知道从何下手的心情。作为一枚刚踏入威士忌大门的“萌新”,我当初也是一脸懵逼,不过别担心,我这趟“小白”之旅,踩过的坑也算不少,今天就来好好跟你聊聊,怎么才能smooth地开始你的威士忌体验,绝不让这篇文章读起来像机器生成的报告!首先,别被威士忌这“高冷”的标签吓.............
  • 回答
    你好,很高兴能和你一起聊聊这几款相机。作为刚入门的朋友,选相机确实容易犯迷糊,毕竟市面上选择太多了。你提到的这几款,索尼 A6400、富士 T30(我猜你指的是 XT30 II,因为它现在是主流)、XS10 和佳能 M6 Mark II,都是各自品牌中非常优秀、且适合入门朋友的APSC画幅微单相机。.............
  • 回答
    你好!非常理解你作为新人作者的急切心情,单机两万字,这是一个不错的开端。你问到题材和写法是否有签约的可能,这是一个非常重要的问题,也是很多新人作者最关心的事情。下面我会尽量详细地为你分析,并且会以一个过来人的角度,告诉你一些实际的考量,力求让我的回复更接地气,更有参考价值。首先,关于“纯新人起点新书.............
  • 回答
    纯内资半导体厂商在车用芯片领域路在何方?中国半导体产业的自主崛起,尤其是在汽车芯片领域的探索,无疑是当下最受关注的产业话题之一。作为“新汽车”的灵魂,车载芯片的性能、安全性和稳定性直接关乎整车的驾驶体验和生命安全。对于我国纯内资的半导体厂商而言,如何在竞争激烈且技术壁垒极高的车用芯片市场中找到一条可.............
  • 回答
    关于纯理性物种能否进化出高等科技,以及无感性是否必然导致科技创新的停滞,这是一个引人入胜且值得深入探讨的话题。我认为,纯理性物种完全有可能进化出高等科技,但我并不完全认同“无感性则无科技创新的说法”。为了更清晰地阐述我的观点,我将从以下几个方面展开:一、理性的力量:科技发展的基石首先,我们需要明确“.............
  • 回答
    纯艺术,这个词本身就带着一种崇高的、似乎与现实工业化社会格格不入的意味。当我们谈论它的“行业”属性时,内心深处或许会泛起一丝疑虑:在一个效率至上、消费主义盛行的时代,纯艺术,那些不以直接实用性为首要考量的创作,真的还有立足之地,甚至发展壮大吗?答案并非简单的“有”或“没有”,而是更加复杂、充满挑战,.............

本站所有内容均为互联网搜索引擎提供的公开搜索信息,本站不存储任何数据与内容,任何内容与数据均与本站无关,如有需要请联系相关搜索引擎包括但不限于百度google,bing,sogou

© 2025 tinynews.org All Rights Reserved. 百科问答小站 版权所有