c语言软件

[CSDN编者注]诞生于1972年的C语言已经有50年的历史了。目前,它像一个20岁的男孩一样充满活力,似乎永远不会退休,它正在赋能世界重量级的应用系统运行。

作者 | Daniel Munoz 编译 | 梦依丹
出品 | CSDN(ID:CSDNnews)

不久前,CSDN发表了一篇观点文章《C不再是编程语言》。作者认为C被提升到了一个有威望有权力的角色,它的统治是绝对的,永恒的,以至于扭曲了开发者与语言的对话方式。目前C是一种通用的编程语言,每个人都必须学习C,这也导致C不再仅仅是一种编程语言,它已经成为每一种通用编程语言都需要遵守的协议。

可见,在当今众多的编程语言中,C语言仍然代表着权威。近日,Meta高性能C++数据仓库工程师Daniel撰文指出,虽然C语言已经问世多年,甚至很多人将其形容为暮光之城,但它仍在为世界编程赋能,并将长期活跃,因为C语言在某些应用中以压倒性优势领先,无与伦比。他列举了C语言是如何渗透到千家万户,影响世界运行的。对此,笔者整理了原文,分享给大家!

c语言软件

今天存在的许多C语言项目都是几十年前开始的:

1969年开发的UNIX操作系统,其代码在1972年基于C语言进行了重构,帮助UNIX系统代码从汇编转移到更高级的语言,从而用更少的代码完成同样的任务;

1977年开发的Oracle也在1983年将代码改为C语言。Oracle是目前最流行的数据库之一。

1985年发布的Window 1.0操作系统,虽然源代码不公开,但据说大部分内核代码也是基于C语言构建的,还有一部分是汇编;

1991年开发的Linux也是基于C语言的。Linux在1992年基于GNU重新授权,并作为GNU操作系统的一部分使用。GNU系统本身也是用C和Lisp编程语言搭建的,所以很多组件都是基于C开发的。

很多人可能会提出,这些系统都是几十年前的项目,当时编程语言还不多,选项就更少了。其实C语言并不局限于几十年前的项目,很多项目都是基于它开始的。

C语言如何驱动世界

编程语言层出不穷,各种高级语言如雨后春笋。但是C语言仍然在为全世界的应用系统提供动力。下面是一些被百万人广泛使用的C语言构造系统。

流行系统中使用的语言。

Windows操作系统

根据NetMarketShare的统计,Windows操作系统的份额常年徘徊在90%左右,服务于全球数十亿用户。它的内核代码大部分是用C语言构建的,也有一部分是基于汇编的。

Linux

众所周知,Linux内核主要是用C语言编写的。在世界上最强大的500台超级计算机中,大约97%运行Linux内核,这也是许多个人电脑使用的内核。

macOS

Mac电脑的操作系统也是由C语言驱动的,因为OS X的大部分内核都是用C语言编写的。Mac里的每一个程序和驱动,就像Windows和Linux的电脑一样,都运行在C语言驱动的内核上。

移动设备

iOS、Android、Windows Phone的内核也是用C语言编写的,只是对现有的Mac OS、Linux、Windows内核的移动适配。所以大家日常使用的智能手机也是运行在C语言上的。

数据库领域

世界上最流行的数据库,包括Oracle,MySQL,MS SQL Server,PostgreSQL,都是用C语言构建的(前三种其实是C和C++)。

数据库用于所有类型的系统:金融、政府、媒体、娱乐、电信、卫生、教育、零售、社交网络、互联网等等。

3D电影

这种应用需要高效和快速。他们需要在几秒钟内进行大量的计算和处理大量的数据,这样艺术家和动画师就可以在更短的时间内生成焦平面,公司也可以节省更多的资金。这些应用大部分也是基于C和C++的。

嵌入式系统

想象一下你某天醒来后的旅行:叫醒你的闹钟大概是用C语言写的,然后你用微波炉或者咖啡机做早餐。它们也是嵌入式系统,所以可能也是基于C语言构建的;当你在早餐时打开电视或收音机,当你用遥控器打开车库门时,你也在使用一个大概是用C语言编程的嵌入式系统。

然后你要开车出去。如果有以下功能,也是用C语言编程的。

自动驾驶

轮胎压力检测系统

传感器(氧气、温度、油位等。).

座椅和后视镜设置的记忆。

仪表板显示

防抱死制动系统

自动稳定性控制

恒速控制器

气候控制

儿童安全锁

无钥匙进入

座椅加热

气囊控制

去商店,停好车,去自动售货机买汽水。那么自动售货机也可能是基于c来构建和运行的,然后你在店里买东西结账,那么收银机也是c,当你用信用卡支付的时候?你猜对了:刷卡器可能也是用C语言写的。

所有这些设备都是嵌入式系统。它们就像带有微控制器/微处理器的小型计算机,在嵌入式设备(也称为固件)上运行程序。该程序必须检测击键并采取相应的行动,并向用户显示信息。例如,闹钟必须与用户进行交互,检测用户按下了什么按钮,有时还会检测按下了多长时间,对设备进行相应的编程,并向用户显示相关信息。例如,汽车的防抱死制动系统必须能够检测到轮胎的突然抱死,并在短时间内采取行动释放制动器上的压力以释放抱死,从而防止失控打滑。所有这些计算都是由编程的嵌入式系统完成的。

虽然不同品牌的嵌入式系统可能使用不同的编程语言,但由于C语言的灵活性、效率、性能和与硬件的接近性,它是开发这些项目的首选。

C语言为什么仍被广泛使用?

今天有很多编程语言可以让开发者开发出比c更高效的应用,这些语言有丰富的内置库,可以简化与JSON、XML、UI、网页、客户端请求、数据库链接、媒体操作等等的工作。尽管如此,在很长一段时间内,C仍然会活跃在编程领域。为什么?

那么我们来看看C语言无可比拟的优势。

可移植性和高效

汇编语言的可移植性差,但C语言是一种可移植性很强的语言。它尽可能地接近机器,并且几乎普遍适用于现有的处理器架构。几乎每个现有的架构都至少有一个C语言编译器。现在因为现代编译器产生的是高度优化的二进制文件,所以用手写汇编提高其输出并不容易。

由于其可移植性和高效性,“其他编程语言的编译器、库和解释器往往都是用C语言实现的”。Python、Ruby、PHP等解释性语言的主要实现都是基于C语言,甚至其他语言的编译器也用C语言与机器进行通信。例如,C是Eiffel和Forth之间的中间语言。意味着这些语言的编译器不需要为要支持的每个架构生成机器码,只需要生成中间的C代码,C编译器处理机器码的生成。

c语言也成为了开发者之间交流的语言。正如Dropbox的工程经理、Cprogramming.com的创始人亚历克斯·阿兰所说:

C语言作为一门伟大的语言,可以让大多数人以能接受的方式来表达编程中的常见想法。此外,C语言在使用中也有语法结构也会出现在其他语言中,例如,用于命令行参数的argc和argv,以及循环结构和变量类型,因此,即使对方不懂C语言,你也能找到一些共同点来与他们交谈。内存操作

内存管理和指针操作是C语言的重要特性,这使得C语言成为系统级编程(操作系统和嵌入式系统)的最佳伙伴。

在硬件/软件边界,计算机系统和微控制器将它们的外设和I/O引脚映射到存储器地址。系统应用程序必须读写这些自定义内存位置,以便与外界通信。因此,C语言操作任何内存地址的能力对于系统编程至关重要。

例如,微控制器可以设计为每当地址0x40008001的第4位设置为1时,存储器地址0x40008000中的字节将由通用异步接收器/发送器(或UART,用于与外设通信的通用硬件组件)发送,并且在设置后将被外设自动取消。让我们演示一个C函数代码,它通过UART发送一个字节:

# define UART _ BYTE *(char *)0x 40008000 # define UART _ SEND *(volatile char *)0x 40008001 | = 0x 08
void SEND _ UART(char BYTE){ UART _ BYTE = BYTE;//将字节写入0x40008000地址UART _ SEND//设置地址0x40008001的第4位send _ UART函数的第一行可以扩展为:

*(char *)0x40008000 =字节;这行代码告诉编译器将0x40008000的值解释为指向char的指针,然后重新定义指针(给出指针指向的值)(使用最左边的*运算符),最后将字节值赋给未定义的指针。换句话说:将变量byte的值写入内存地址0x40008000。

展开此函数的下一行代码:

*(volatile char *)0x 40008001 | = 0x 08;在这行代码中,我们对地址0x40008001和值0x08(二进制00001000,即第4位1)进行了or运算,并将结果保存回地址0x40008001。换句话说,我们设置地址为0x40008001的字节的第四位。我们还声明地址为0x40008001的值是易变的。这告诉编译器,该值可能会被我们代码之外的进程修改,因此编译器在写入地址后不会对其值做出任何假设。(在这种情况下,我们用软件设置后,字节被UART硬件取消)。这些信息对于编译器的优化器非常重要。例如,如果我们在For循环中这样做,而没有指定该值是volatile,编译器可能会认为该值在设置后永远不会改变,并在第一次循环后跳过执行该命令。

确定资源使用

开发者进行系统编程不能依赖的一个常见语言特性就是垃圾回收,甚至对于一些嵌入式系统来说,只能动态分配。嵌入式应用在时间和内存资源方面非常有限。对于一些实时嵌入式系统来说,无法承受垃圾收集器的不确定性调用。如果因为内存不足而无法使用动态分配,那么拥有其他内存管理机制就显得尤为重要,比如像C语言中指针所允许的那样,将数据放在自定义地址中。严重依赖动态分配和垃圾收集的语言不适合资源紧张的系统。

Code Size

c语言的运行时非常小,代码占用的内存也比其他语言少。例如,与C++相比,C语言生成的二进制文件的体积大约是同类C++代码的一半。造成这种情况的一个主要原因就是畸形供养。

与C语言相比,异常机制是C++的一个很好的功能。如果不触发异常并巧妙实现,实际上没有执行时间开销,但代价是增加代码量。

让我们以C++代码为例:

//A类声明。在其他地方定义的方法;A类{ public:A();//构造函数~ A();//析构函数(对象超出范围或被删除时调用)void my method();//只是一个方法};
//B类声明。在其他地方定义的方法;B类{ public:B();//构造函数~ B();//析构函数void my method();//只是一个方法};
//C类声明。在其他地方定义的方法;C类{ public:C();//构造函数~ C();//析构函数void my method();//只是一个方法};
void my function(){ A A;//构造函数a.A()被调用。(检查点1){ B B;//调用了构造函数b.B()。(检查点2)b . my method();//(检查点3) } // b.~B()析构函数被调用。(检查点4){ C C;//调用了构造函数c.C()。(检查点5)c . my method();//(检查点6) } //调用了c.~C()析构函数。(检查点7)a . my method();//(检查点8)}//A. ~ A()破坏者调用。(检查点9)这段代码中A类、B类、C类的方法都是外部定义的(比如在其他文件中)。因此,编译器无法解析它们,也不知道是否会引发异常。因此,程序必须准备好处理从它们的任何构造函数、析构函数或其他方法调用中抛出的异常。析构函数不应该抛出(这很不好),但是用户还是可以抛出,或者可以通过调用一些抛出异常的函数或方法(显式或隐式)来间接抛出。

如果myFunction中的任何调用抛出异常,堆栈展开机制必须能够调用所有构建对象的析构函数。堆栈展开机制的一个实现将使用该函数最后一次调用的返回地址来验证触发异常的调用的“检查点号”(这是一个简单的解释)。它是通过使用辅助的自动生成函数(一种查找表)来实现的。当函数主体抛出异常时,该函数将用于堆栈展开,这将是类似的。

如果任何对myFunction的调用抛出异常,C++的栈展开机制必须能够调用所有构建对象的析构函数。栈扩展机制的一种实现是利用该函数最后一次调用的返回地址来验证触发异常调用的“检查点号”(这是一个简单的解释)。这是通过使用辅助自动生成功能(一种查找表)来实现的。当这个函数的主体抛出异常时,这个函数将被用于栈展开,类似于下面的代码:

//可能自动生成的函数void autogeneratedStackUnwindingFor _ my function(int check point){ switch(check point){//情况1和9:什么都不做;案例三:B . ~ B();goto destroyA//跳转到destroyA标签case 6的位置:C . ~ C();//也转到destroyA,因为那是下一行destroyA://label case 2:case 4:case 5:case 7:case 8:A . ~ A();}}如果从情况1和9抛出异常,则没有要销毁的对象。对于情况3,那么b和a必须被销毁。对于情况6,必须销毁c和a。在所有情况下,必须遵守销毁的顺序。对于检查点2、4、5、7和8,只有对象A需要销毁。

这个辅助函数增加了代码的大小。这是C++给C语言增加的空之间开销的一部分。许多嵌入式应用无法承受这种额外的空空间。因此,嵌入式系统中使用的C++编译器通常会有一个标志来禁用异常。在C++中禁用异常是不自由的,因为标准模板库严重依赖异常来通知错误。使用这种修改后的方案,没有任何异常,C++开发人员需要更多的训练来检测可能存在的问题或发现错误。

C++的一个原则是“开发者不必为他们不使用的东西付费”。对于其他语言,二进制量的增加会变得很糟糕,通过其他函数增加额外开销。虽然这些功能很有用,但是嵌入式系统负担不起。虽然C语言不会给你提供这些额外的函数,但是它可以有比其他语言更紧凑的代码占用空间,占用更小的磁盘空。

为什么要学C语言?

c语言不难学。作为一门老的编程语言,有很多关于它的教程和学习资料。学习C语言有什么好处?

通用语言

C语言是开发人员的通用语言,互联网上或书本上的很多算法都是基于C语言实现的,这也为实现提供了最大的可移植性,开发人员将从中受益。

Understand the Machine(用C语言思考)

当我们和同事讨论代码的某些部分或者其他语言的某些特性时,最终会“用C语言说话”:“这部分是传递一个指向对象的“指针”还是复制整个对象?这里会有什么“转变”吗?等一下。

在分析高级语言中某些代码的行为时,我们很少讨论(或思考)某些代码正在执行的汇编指令。相反,在讨论机器在做什么的时候,我们可以用C语言描述(或者思考)清楚。

在许多有趣的C语言项目上工作

从一个大型的数据库服务器或者操作系统内核甚至是一个供个人享乐的小型嵌入式应用,都可以用C语言实现,也可以在网上找到相关的Demo。丹尼尔呼吁大家不要停止做自己喜欢的事情,比如学习C语言,这是一门古老而又渺小的语言,是一门经过时间考验的编程语言。

总结

目前很多编程语言的预设用途都优于C,但这并不意味着C可以被打败。在性能优先的情况下,C依然是王道。世界运行在C语言驱动的设备上。不管你有没有意识到,你用的很多设备确实是用C语言的。

原文链接:https://www . top tal . com/c/after-all-these-the-world-is-powered-by-c-programming。

结束

实现1亿技术人

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。

发表回复

登录后才能评论