C语言不是最好的,却是我最爱的~

点击蓝字

6268cb802cb818e3a56cfcf7a6601663.png

关注我们

因公众号更改推送规则,请点“在看”并加“星标”第一时间获取精彩技术分享

来源于网络,侵删

以下为译文:

虽然 C 语言并不是我所学的第一门语言,也不是我的最后一门语言,但是我仍然非常喜欢 C,当需要写程序时,我的第一选择还是 C。同时,我也会关注现代编程语言及其发展趋势,而且我还使用 Rust 编写了自己的业务爱好项目。那么,为什么我没有抛弃 C 而选择其他语言呢?我对于 C++的看法又是如何的呢?

1、为什么说C不是最好的语言?

首先,这个世上没有最好的编程语言。每种语言都有独特的优势以及适用情况,所以尽管你可以在 Excel 中编写光线追踪程序,但最好还是使用其他语言。因此,我们都需要了解编程语言的限制,不要抱怨 Web 服务器不是用 Fortran 编写的,也不要抱怨基本没有任何应用使用 Perl 或 C++作为内部脚本语言。我认为 C 语言不太理想的方面包括以下几点(除了 C 比较老,发展不快之外,当然还与个人的喜好有关)。

其次,有些时候,C 的语言不够明确。比如,*可以是二进制乘法运算符、一元解引用运算符,也可用于声明指针。

再者,有些情况不够安全,例如越界访问数组这种极其常见的错误都没有运行时检查,这一点连 Borland Pascal 都比不了,更不用说更现代的编程语言了(尽管你会为了提高性能关闭这个编译选项)。此外,指针让我们很难保持一切井然有序。再加上一些其他情况,比如调用函数不需要事先声明原型,这样很容易将错误类型的参数传递给函数。

最后,C 的标准库非常有限。有些编程语言甚至拥有开箱即用的 Web 服务器(或者至少有构建 Web 服务器所需的所有模块),但 C 标准库甚至连 Web 服务器的容器也没有。

2、为什么我还是喜欢C?

尽管如此,我还是十分喜欢 C,因为它是一种简单的语言。从某种意义上说很简单,很容易表达自己的想法以及期望。

举个例子,假设两个数组有两个偏移量,其中一个可以为负数,如果使用C语言编写,则可以写成:

arr[off1 + off2]

如果是Rust,则需要写成:

arr[((off1 as isize) + off2) as usize]

通常,C 的循环也比 Rust 的迭代器组合更为简洁(当然 Rust 也允许使用前一种方式,但 linter 并不满意,它会建议你使用迭代器来代替)。类似地,memset()和 memmove()也是功能十分强大的工具。

在大多数情况下,你都可以预见到编译的结果,即对象在内存中的表示方式,以及如何通过不同的方式理解编译后的结果(新版 C 标准中这一点变得更困难,这都要怪 C++,我稍后再详细介绍)。另外,你也很清楚函数调用的结果等等。由于这个原因,C 被称为可移植的汇编语言,所以我非常喜欢 C。

在公众号【C语言中文社区】回复“C语言”三个字,免费领取500G精品编程资料

我们拿汽车做个类比,C 语言就像一辆跑车,拥有手动变速箱,可以提供最佳性能,但是如果你不熟悉离合器和挂挡操作,那么变速箱很容易被损坏,甚至可能损坏发动机,当然,油门踩得过大也有可能冲出马路。然而,与自动变速箱相比,这种车辆的发动机能量更大,而且你可以预测性能,还可以炫车技,这些在其他车辆上都是不可能的。

3、这与C++有什么关系?

下面,我们来说一说 C++,其实我不讨厌 C++。我不能否认,与 C 相比, C++ 拥有两个优点:

  • 更好的程序结构:C++ 拥有命名空间和类,而且在某些方面Simula还是很出色的。

  • 拥有 RAII 概念:一个简单的例子就是 C++ 拥有构造函数,可在创建对象时初始化对象;还拥有析构函数,在销毁对象时,做一些清理的工作。这个概念进一步发展,就接近 Rust 的生命周期了。

另一方面,C++ 有两个特征,我非常不喜欢。 

首先是这门语言的整体性质。其他编程语言拥有的流行功能最终都会进入 C++。因此,每过几年,C++标准就会添加一些新功能。最终,这门语言就变得有点怪异,没人能够完全掌握,而且许多功能都是抄袭的其他语言。基本上每个人在编写代码的时候,都会选择一个 C++的子集,然后忽略其他功能的存在。另外,我们究竟应该使用哪个 C++版本的功能,并没有一套标准的方法。Rust 在包的范围内提供了版本管理。据我所知,C++也曾尝试过引入“代际”的概念来实现同样的功能,但没有成功。我经常听到有人独自编写 C 编译器,却从来没听说过有人编写 C++编译器。

其次,实际上 C++不仅是多种语言,而且还是一种元语言(即模板)。我了解 C++的创建初衷,也同意它对于与类型无关的代码的处理,比 C 预处理器更好。但实际上,它产生的代码十分可怕,原本是“头文件仅包含声明,实现放在编译好的代码中”,变成了“头文件包含所有项目会用到的代码”。我不喜欢过于冗长的编译时间,但这种方式只能让情况更糟。

最后,我觉得 C++的出现反而给 C 带来了约束以及不良影响。我不是在讨论 C/C++,也不是指 C 与 C++的共通之处,我讨论的是耦合对标准和编译器都有不良影响。一方面,C++建立在 C 之上,从而得到了极大的发展;另一方面,如果 C++中没有 C 遗留下来的大多数功能的话,情况可能会更好(当然,C++曾设法通过淘汰的方式逐步放弃某些 C 功能,但对于旧功能的支持仍然存在)。但是,C++ 24 能够在 C++ 21 的基础之上,发展成为一门独立的编程语言吗?大多数过时的功能都可以抛弃吗?我对此表示怀疑。

4、C++编译器对C的影响

实际上,C 语言被当成了没有某些功能的 C++。比如微软的 C 编译器直到2015 版才开始支持 C99 功能(即便如此,它还是以 bug 修复 bug 的方式来支持兼容性,因为客户可能会震惊地发现可变参数宏居然可以运行)。但是,无论是标准的编译器还是其他编译器中都可以看到相同的方法,这些都是相关的问题。 

主要问题在于,C 和 C++标准都是根据编译器开发人员的反馈而编写的,而且大多数都是 C++开发人员(有些人对现实世界编程一无所知,而且他们还认为现实世界的做法与自己的观点完全吻合,真是令人窒息的操作)。虽然我也没有遵循标准的开发程序,但是我很确定 C99 及其后版本中令人讨厌的诸多功能皆来自那些编译器开发人员。他们只从 C++的角度出发考虑,而且还将这些功能强加给了 C,还美其名曰简化编译器。

当然我指的是“未定义的行为”以及编译器的处理方式。这已成为一大毒瘤(只要你的代码依赖于二进制补码算术,就会被认定具有未定义的行为,编译器会抛弃整块代码)。

在我看来,以下四种行为尽管不值得提倡,但前两个也并非不可接受:

  • 依赖于体系结构的行为(即依赖于 CPU 体系结构的行为)。包括绝大部分算术运算。例如,如果我知道目标及其使用了两个协处理器,为什么编译器会选择另一种方式,仅仅是为了获得理论上的优化?同样的问题也适用于移位运算。如果我知道 x86 会忽略移位偏移量的高比特,在 ARM 上负的左移相当于右移,那么为什么不能专门针对该体系结构编写程序呢?毕竟,连整数的大小在不同平台上都不一样。这种不可移植性只需警告就好,让用户自行处理。

  • 指针魔法和类型双关。这似乎又是编译器优化带来的限制。我同意,在重叠的内存区域上使用 memcpy(),不同的实现可能会给出不同的行为(现代的 x86 实现会从区域尾部开始复制),而且还依赖于地址的相对位置,但其他的规则就没什么道理了。例如,无法使用两个不同类型的指针同时操作同一块内存区域。我无法想象为什么这种行为被禁止,其原因只可能是编译器优化。这样就不可能利用联合体将整数转换成浮点数。Linus 也曾吐槽过这一点,我就不用重复了。但在我看来,这样做的目的或者是更好的编译器优化,或者是出于 C++的要求(由于类型跟踪的要求)。

  • 实现中定义的行为(即超出 C 标准规定的行为)。我常用的例子就是函数调用:根据调用的习惯约定和编译器的实现,函数的参数的求值顺序可能完全是随机的,因此 foo(*ptr++, *ptr++, *ptr++)的结果是未定义的,因此即使你知道目标体系结构,也不应该依赖于这种行为。

  • 完全未定义的行为。最常见的例子就是在一条语句中改变变量状态,例如著名的 I++ + i++,或者更甚的 *ptr++ = *ptr++ +*ptr++。

由于 C++比 C 更高级(尽管它由许多来自 C 的特性,但都不建议使用,应该使用 reinterpret_cast<>代替类型转换,用引用代替指针,等等),所以不要期待 C++程序员能够像 C 程序员那样理解底层代码。当然,由于 C++程序员占绝大多数,C/C++的耦合也极其常见,所以 C 编译器通常会进行扩展以支持C++,并使用 C++重写,以适应其复杂度。所以很不幸,你不得不使用 C++编译器来编译 C 编译器(还好我们还有 LCC、PCC 和 TCC 等纯 C 编译器)。

5、总    结 

总的来说,我喜欢C所处的中层位置,它既可以完成一些底层的实现,例如轻松地操作内存,同时又可以享受高级语言的好处。另一方面,我对C++强烈的不满来自其在设计上的选择,而且这些设计影响了C标准和编译器。

至少我不可能用 C90 特别版取代 C90,并假装原来的版本不存在。

原文转于: 作者 | Kostya Shishkov,译者 | 弯月  责编 | 欧阳姝黎 ,出品 | CSDN(ID:CSDNnews)原文链接:

https://codecs.multimedia.cx/2021/05/why-i-still-like-c-and-strongly-dislike-cpp/

版权归原作者或平台所有,仅供学习参考与学术研究,如有侵权,麻烦联系删除~感谢

最后

      好了,今天就跟大家分享这么多了,如果你觉得有所收获,一定记得点个~

如果你年满18周岁以上,又觉得学【C语言】太难?想尝试其他编程语言,那么我推荐你学Python,现有价值499元Python零基础课程限时免费领取,限10个名额!
▲扫描二维码-免费领取

戳“阅读原文”我们一起进步

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/337006.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

lucene 源码分析_Lucene分析过程指南

lucene 源码分析本文是我们名为“ Apache Lucene基础知识 ”的学院课程的一部分。 在本课程中&#xff0c;您将了解Lucene。 您将了解为什么这样的库很重要&#xff0c;然后了解Lucene中搜索的工作方式。 此外&#xff0c;您将学习如何将Lucene Search集成到您自己的应用程序中…

ggplot2箱式图两两比较_R语言进阶笔记2 | 长数据与ggplot2

1. 长数据是什么鬼&#xff1f;之前介绍了如何将多个性状的箱线图放在一个图上&#xff0c;比如learnasreml包中的fm数据&#xff0c;它有h1~h5五年的株高数据&#xff0c;想对它进行作图。「数据预览&#xff1a;」> library(learnasreml)> data(fm)> head(fm) Tree…

面向对象,C语言实现简单工厂模式,思路+代码

点击蓝字关注我们因公众号更改推送规则&#xff0c;请点“在看”并加“星标”第一时间获取精彩技术分享来源于网络&#xff0c;侵删1、简介简单工厂方法定义一个用于创建对象的类&#xff0c;该类接受一个参数&#xff0c;通过参数决定创建不同的对象。GOF并没有把简单工厂方法…

javaone_JavaOne和OOW 2015总结

javaone大家好&#xff01; 终于&#xff0c;我回来了一个很棒的JavaOne和OOW2015。在这篇文章中&#xff0c;我想分享我的经验&#xff0c;一些照片和我参加的演讲的摘要。 会议前 我于2015年6月24日星期六乘Copa航空公司CLO-PTY-SFO飞往旧金山。 从哥伦比亚出发&#xff08;…

如何导出久其报表所有数据_如何选择好的HR软件

相信HR朋友想要换HR系统的时候&#xff0c;一般都会在百度、360和搜狗上找&#xff0c;或者通过朋友介绍&#xff0c;而自己百度找的时候&#xff0c;就会出现很多HR软件的广告&#xff0c;一个一个的去问&#xff0c;也不一定能问出所以然&#xff0c;所以就约着面谈&#xff…

网站快速变灰色,几行代码就搞定了!

点击蓝字关注我们因公众号更改推送规则&#xff0c;请点“在看”并加“星标”第一时间获取精彩技术分享来源于网络&#xff0c;侵删自从伟大的江爷爷走了后&#xff0c;全站和各个App的内容都变成了灰色&#xff0c;包括按钮、图片等等。这时候我们可能会好奇这是怎么做到的呢&…

java 递归 堆栈_Java中的堆栈安全递归

java 递归 堆栈在本文中&#xff0c;摘自《 Java中的函数编程 》一书&#xff0c;我解释了如何使用递归&#xff0c;同时避免了StackOverflow异常的风险。 Corecursion正在使用第一步的输出作为下一步的输入来构成计算步骤。 递归是相同的操作&#xff0c;但是从最后一步开始。…

cshtml中引用css_css基础必备-使用样式,前端小白一看就会

在HTML文档中包含CSSCSS可以作为单独的文档引用&#xff0c;也可以嵌入到HTML文档中。在HTML文档中包含CSS有三种方法&#xff1a;内联样式 - 使用元素起始标记的style属性指定样式嵌入样式 - 在文档的head部分使用style标记指定样式外部样式 - 在文档的head部分使用link标记引…

嵌入式软件分层框架设计,举个例子

点击蓝字关注我们因公众号更改推送规则&#xff0c;请点“在看”并加“星标”第一时间获取精彩技术分享来源于网络&#xff0c;侵删前言为了能够使得产品得到更好的开发速度与以后更好的迭代和移植&#xff0c;框架分层是很有必要的。但如对于中小型项目严格遵循这些原则&#…

腾讯大举退出美团!

点击蓝字关注我们因公众号更改推送规则&#xff0c;请点“在看”并加“星标”第一时间获取精彩技术分享来源于网络&#xff0c;侵删11月16日&#xff0c;腾讯发布第三季度财报&#xff0c;同时表示将“分红式减持”美团。腾讯分派90.9%美团持股 腾讯系中概股美股盘前多数下跌腾…

matchers依赖_Hamcrest Matchers教程

matchers依赖本文是我们名为“ 用Mockito测试 ”的学院课程的一部分。 在本课程中&#xff0c;您将深入了解Mockito的魔力。 您将了解有关“模拟”&#xff0c;“间谍”和“部分模拟”的信息&#xff0c;以及它们相应的存根行为。 您还将看到使用测试双打和对象匹配器进行验证…

谷歌开源替代 C++ 的编程语言:Carbon

点击蓝字关注我们因公众号更改推送规则&#xff0c;请点“在看”并加“星标”第一时间获取精彩技术分享来源于网络&#xff0c;侵删谷歌工程师 Chandler Carruth 近日在多伦多举办的 CppNorth 大会上宣布①&#xff0c;正式开源谷歌内部打造的编程语言&#xff1a;Carbon&#…

C语言灵魂拷问:++i为何比i++执行效率高!有何区别?

点击蓝字关注我们因公众号更改推送规则&#xff0c;请点“在看”并加“星标”第一时间获取精彩技术分享来源于网络&#xff0c;侵删背景相信很多人遇到过这样的问题&#xff1a;printf("%d,%d",i,i);也纠结过这个问题&#xff0c;到底答案是什么。确没有一个参考的资…

指标实现层级_企业如何构建核心指标系统,实现业务运营效率提升90%?

本文为帆软数据生产力大赛获奖案例&#xff0c;未经授权禁止转载。01企业简介西安怡康医药连锁有限责任公司成立于2001年&#xff0c;总部设在西安市大庆路副24号,是一家由零售连锁药店发展起来的大型医药连锁企业&#xff0c;除药品零售外&#xff0c;同时兼营药品批发与器械批…

学生时代,你有遇到过像我这样理解C语言的吗?

点击蓝字关注我们因公众号更改推送规则&#xff0c;请点“在看”并加“星标”第一时间获取精彩技术分享来源于网络&#xff0c;侵删今天我讲一下我个人对C语言的认识以及自己的理解&#xff0c;若有错误&#xff0c;还望指出&#xff0c;不甚感激。首先是C语言整体的脉络&#…

scrapyd部署_第八章 第一节 scrapyd和scrapy-client

如果觉得文章对您产生帮助的话, 欢迎关注Python开发之路(微信公众号: python-developer), 及时获取更多教程假设有我们做了一个项目是抓取很多网站(每个网站对应一个爬虫), 需要分别部署到不同的服务器上(单台扛不住), scrapy官方也提供了一种部署工具scrapyd。这个工具是用来将…

C++ 首超 Java,与 Python、C语言共角逐年度最佳编程语言奖!

点击蓝字关注我们因公众号更改推送规则&#xff0c;请点“在看”并加“星标”第一时间获取精彩技术分享来源于网络&#xff0c;侵删最新的 TIOBE 12 月编程语言已发布&#xff0c;先来预测一波今年的年度编程语言大奖究竟会花落谁家吧&#xff1f;C 首超 Java和上个月相比&…

乔安监控云存储能存多长时间_干货 | 监控磁盘阵列知识介绍,不了解还不来看看?...

一、磁盘阵列的概念要定义磁盘阵列的概念&#xff0c;是一个简单的工作&#xff0c;因为这个概念已经形成了共识——磁盘阵列(DiskArray)是由一个硬盘控制器来控制多个硬盘的相互连接&#xff0c;使多个硬盘的读写同步&#xff0c;减少错误&#xff0c;增加效率和可靠度的技术。…

我要是在学习 C 语言之前知道这些就好了!

点击蓝字关注我们因公众号更改推送规则&#xff0c;请点“在看”并加“星标”第一时间获取精彩技术分享来源于网络&#xff0c;侵删对于我来说&#xff0c;学习 C 语言好难啊。这门语言本身的基础知识并不是很难&#xff0c;但是“用 C 语言编程”需要用到各种知识&#xff0c;…

opencv yuv保存本地_OpenCV-dlib-python3实现人脸戴墨镜和含Y的抖音效果

1 说明&#xff1a;1.1 吸烟有害健康&#xff01;&#xff01;纯属娱乐和学习python的相关知识。1.2 虽然是娱乐&#xff0c;但是opencv、dlib和python在人工智能、人脸识别、自动化等有很大作用&#xff0c;目前已经或者未来会有更多的应用&#xff0c;作为一名普通人&#xf…