【嵌入式智能产品开发实战】(十五)—— 政安晨:通过ARM-Linux掌握基本技能【GNU C标准与编译器】

目录

GNU C

什么是C语言标准

C语言标准的内容

C语言标准的发展过程

1.K&R C

2.ANSI C

3.C99标准

4.C11标准

编译器对C语言标准的支持

编译器对C语言标准的扩展


政安晨的个人主页政安晨

欢迎 👍点赞✍评论⭐收藏

收录专栏: 嵌入式智能产品开发实战

希望政安晨的博客能够对您有所裨益,如有不足之处,欢迎在评论区提出指正!

GNU C

大家在看一些GNU开源软件,或者阅读Linux内核、驱动源码时会发现,在Linux内核源码中,有大量的C程序看起来“怪怪的”。

说它是C语言吧,貌似又和教材中的写法不太一样;

说它不是C语言吧,但是这些程序确确实实保存在一个C源文件中。

此时,你肯定怀疑你看到的是一个“假的”C语言!

例如,下面的宏定义:

字符驱动的填充如下:

内核中实现打印功能的宏定义如下:

你没有看错,这些其实也是C语言,但并不是标准的C语言语法,而是在Linux内核中大量使用的GNU C编译器扩展的一些C语言语法。这些语法在C语言教材中一般不会提及,所以你才会似曾相识而又感到陌生,看起来感觉“怪怪的”。

我们在Linux驱动开发,或者阅读Linux内核源码过程中,会经常遇到这些“稀奇古怪”的用法,如果不去了解这些特殊语法的具体含义,可能就会对我们理解代码造成一定障碍。

什么是C语言标准

什么是C语言标准?我们生活的世界是由各种标准和规则构成的,正是因为有了这些标准,我们的社会才会有条不紊地运行下去。我们过马路时遵循的交通规则就是一个标准:红灯停,绿灯行,黄灯亮了等一等。当行人和司机都遵循这个标准时,交通系统才能顺畅运行。

计算机的USB接口也有一种标准,当不同厂家生产的USB设备都遵循USB协议这个通信标准时,鼠标、键盘、手机、U盘、USB摄像头、USB网卡才可以在各种计算机设备上即插即拔,相互通信。2G、3G、4G、5G、6G、7G...也都有一种标准,当不同厂家生产的基带芯片都遵循这种通信标准时,不同品牌、不同操作系统的手机才可以互相打电话、发信息、给对方点赞。

同样的道理,C语言也有它自己的标准。

C语言程序通过编译器,参考不同架构的指令集,编译生成对应的二进制指令,才能在不同架构的处理器上运行。

在C语言早期,各大编译器厂商在开发自己的编译器时,各自开发,各自维护,时间久了,就变得比较混乱,造成这样一种局面:程序员写的程序,在一个编译器上编译可以通过,在另一个编译器上编译可能就通不过。

大家按照各自的习惯来,谁也不服谁,就像春秋战国时期,不同的货币、不同的度量衡、不同的文字,都是中国人,因为标准不统一,所以交流起来很麻烦,这样下去也不是办法。

后来美国国家标准协会(American National Stardards Institude,ANSI)联合国际化标准组织(International Organization for Standardization,ISO)召集各个编译器厂商和各种技术团体一起开会,开始启动C语言的标准化工作

期间各种大佬之间也是矛盾重重,充满各种争议,但功夫不负有心人,经过艰难的磋商,终于在1989年达成一致,发布了第一版C语言标准,并在第二年做了一些改进。于是,就像秦始皇统一六国,统一文字和度量衡一样,C语言标准终于问世了。C语言标准因为是在1989年发布的,所以人们一般称其为C89或C90标准,或者叫作ANSI C标准。

C语言标准的内容

C语言标准主要讲了什么内容?

打开C语言标准文档,洋洋洒洒几百页,讲了很多东西,但总体归纳起来,主要就是C语言编程的一些语法惯例、约定规则,如在C语言标准里

● 定义各种关键字、数据类型。

● 定义各种运算规则、各种运算符的优先级和结合性。

● 数据类型转换。

● 变量的作用域。

● 函数原型、函数嵌套层数、函数参数个数限制。

● 标准库函数接口。

C语言标准发布后,大家都遵守这个标准开展工作

程序员开发程序时,按照这种标准规定的语法规则编写程序;

编译器厂商开发编译器工具时,也按照这种标准去解析、翻译程序。

不同的编译器厂商支持统一的C语言标准,我们编写的同一个程序使用不同的编译器都可以正常编译和运行。

C语言标准的发展过程

C语言标准并不是永远不变的,就和无限通信标准一样,也是从2G、3G、4G到5G等等不断发展变化的。

C语言标准也经历了下面4个阶段:

● K&R C

.● ANSI C.

● C99.

● C11.

1.K&R C

K&R C一般也称为传统C在C语言标准没有统一之前,C语言的作者Dennis M.Ritchie和Brian W.Kernighan合作写了一本书《C程序设计语言》。早期程序员编程,这本书可以说是绝对权威的。这本书很薄,内容精炼,主要介绍了C语言的基本编程语法。后来《C程序设计语言》第二版问世,做了一些修改,如新增unsigned int、long int、struct等数据类型;把运算符=+/=-修改为+=/-=,避免运算符带来的一些歧义和bug。第二版可以看作ANSI标准的雏形,但早期的C语言还是很简单的,如还没有定义标准库函数、没有预处理命令等。

2.ANSI C

ANSI C是ANSI在K&R C的基础上,统一了各大编译器厂商的不同标准,并对C语言的语法和特性做了一些扩展,在1989年发布的一个标准。这个标准一般也叫作C89/C90标准,也是目前各种编译器默认支持的C语言标准。ANSI C标准主要新增了以下特性。

● 增加了signed、volatile、const关键字。

● 增加了void*数据类型。

● 增加了预处理器命令。

● 增加了宽字符、宽字符串。

● 定义了C标准库。

● ……

3.C99标准

C99标准是ANSI在1999年基于C89标准发布的一个新标准。该标准对ANSI C标准做了一些扩充,如新增了一些关键字,支持新的数据类型。

● 布尔型:_Bool。

● 复数:_Complex。

● 虚数:_Imaginary。

● 内联:inline。

● 指针修饰符:restrict。

● 支持long long、long double数据类型。

● 支持变长数组。

● 允许对结构体特定成员赋值。

● 支持十六进制浮点数、float_Complex等数据类型。

● ……

C99标准也会借鉴其他编程语言的一些优点,对自身的语法和标准做一系列改进,例如:

变量声明可以放在代码块的任何地方。ANSI C标准规定变量的声明要全部写在函数语句的最前面,否则就会报编译错误。现在不需要这样写了,哪里需要使用变量,直接在哪里声明即可。

源程序每行最大支持4095字节。这个貌似足够用了,没有什么程序能复杂到一行程序有4000多个字符。

支持//单行注释。早期的ANSI C标准使用/**/注释,不如C++的//注释方便,所以C99标准就把这种注释吸收过来了,从C99标准开始也支持这种注释方式。

标准库新增了一些头文件,如stdbool.h、complex.h、stdarg.h、fenv.h等。大家在C语言中经常返回的true、false,其实这是C++里面的定义的bool类型,早期的C语言是没有bool类型的。那为什么我们经常这样写,而编译器编译程序时没有报错呢?

这是因为早期大家编程使用的都是VC++6.0系列,使用的是C++编译器,C++编译器是兼容ANSI C标准的。当然还有一种可能就是有些IDE对这种数据类型做了封装。

4.C11标准

C11标准是ANSI在2011年发布的最新C语言标准,C11标准修改了C语言标准的一些bug,增加了一些新特性。

● 增加_Noreturn,声明函数无返回值。

● 增加_Generic,支持泛型编程。

● 修改了标准库函数的一些bug,如gets()函数被gets_s()函数代替。

● 新增文件锁功能。

● 支持多线程。

● ……

从C11标准的新增内容,我们可以观察到C语言未来的发展趋势。

C语言现在也在借鉴现代编程语言的优点,不断添加到自己的标准里。如现代编程语言的多线程、字符串、泛型编程等,C语言最新的标准都支持。但是这样下去,C语言会不会变得越来越臃肿?是不是还能保持它“简单就是美”的初心呢?这一切只能交给时间了,至少目前我们不用担心这些,因为新发布的C11标准,目前绝大多数编译器还不支持,我们暂时还用不到。(呵呵)

编译器对C语言标准的支持

标准是一回事,编译器支不支持是另一回事,这一点,大家要搞清楚。这就和手机一样,不同时期发布的手机对通信标准支持也不一样:早期的手机可能只支持2G,后来支持3G,现在发布的新款手机基本上都支持4G了,而且可以兼容2G/3G。现在5G标准普及了,6G就来了。

不同编译器对C语言标准的支持也不一样。有的编译器只支持ANSI C标准,这是目前默认的C语言标准。有的编译器可以支持C99标准,或者支持C99标准的部分特性。目前对C99标准支持最好的是GNU C编译器,据说可以支持C99标准99%的新增特性。

编译器对C语言标准的扩展

不同编译器,出于开发环境、硬件平台、性能优化的需要,除了支持C语言标准,还会自己做一些扩展。

在51单片机上用C语言开发程序,我们经常使用Keil for C51集成开发环境。你会发现Keil for C51或者其他IDE里的C编译器会对C语言做很多扩展,如增加了各种关键字。

● data:RAM的低128B空间,单周期直接寻址。

● code:表示程序存储区。

● bit:位变量,常用来定义51单片机的P0~P3管脚。

● sbit:特殊功能位变量。

● sfr:特殊功能寄存器。

● reentrant:重入函数声明。

如果你在程序中使用以上这些关键字,那么你的程序只能使用51编译器来编译运行;如果你使用其他编译器,如VC++6.0,则编译是通不过的。

同样的道理,GCC编译器也对C语言标准做了很多扩展。

● 零长度数组。

● 语句表达式。

● 内建函数。

● __attribute__特殊属性声明。

● 标号元素。

● case范围。

● ……

如支持零长度数组,这些新增的特性,C语言标准目前是不支持的,其他编译器也不支持。如果你在程序中定义一个零长度数组:

则只能使用GCC编译器才能正确编译,使用VC++6.0编译器编译可能就通不过,因为Microsoft的C++编译器不支持这个特性。


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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

QA测试开发工程师面试题满分问答6: 如何判断接口功能正常?从QA的角度设计测试用例

判断接口功能是否正常的方法之一是设计并执行相关的测试用例。下面是从测试QA的角度设计接口测试用例的一些建议,包括功能、边界、异常、链路、上下游和并发等方面: 通过综合考虑这些测试维度,并设计相应的测试用例,可以更全面地评…

【机器学习】“强化机器学习模型:Bagging与Boosting详解“

1. 引言 在当今数据驱动的世界里,机器学习技术已成为解决复杂问题和提升决策制定效率的关键工具。随着数据的增长和计算能力的提升,传统的单一模型方法已逐渐无法满足高精度和泛化能力的双重要求。集成学习,作为一种结合多个学习算法以获得比…

大数据实验二-HDFS编程实践

一.实验内容 HDFS编程实践: 1)使用HDFS文件操作的常用Shell命令; 2)利用Hadoop提供的Java API进行基本的文件操作。 二.实验目的 1、理解HDFS在Hadoop体系结构中的角色。 2、熟练使用HDFS操作常用的Sh…

【测试篇】接口测试

接口测试,可以用可视化工具 postman。 如何做接口测试?? 我们可以先在浏览器中随机进入一个网页,打开开发者工具(F12)。 随便找一个接口Copy–>Copy as cURL(bash) 打开postman 复制地址 进行发送。 …

CF1717 D. Madoka and The Corruption Scheme [思维题?]

传送门:CF [前题提要]:近期在集中刷1900的题,原本感觉这类题的思维难度对自己来说似乎没什么大问题,拿到手之后就开始乱贪心,然后就Wa4了,狠狠地被这道题给教育了,故记录一下 看了题解之后感觉这种做法之前在某道题中碰到过类似的,但是想不起来了… 我个人认为这道题的关键点…

时间管理系统的设计与实现|Springboot+ Mysql+Java+ B/S结构(可运行源码+数据库+设计文档)大学生

本项目包含可运行源码数据库LW,文末可获取本项目的所有资料。 推荐阅读300套最新项目持续更新中..... 最新ssmjava项目文档视频演示可运行源码分享 最新jspjava项目文档视频演示可运行源码分享 最新Spring Boot项目文档视频演示可运行源码分享 2024年56套包含ja…

打印日志(JAVA)

1、通过导入包的形式 package com.example.demo;import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; RequestMapping("/log&q…

文章解读与仿真程序复现思路——电网技术EI\CSCD\北大核心《考虑灵活性供需平衡的新型电力系统长短期储能联合规划》

本专栏栏目提供文章与程序复现思路,具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 电网论文源程序-CSDN博客电网论文源…

垄断与商品化背景下的网络安全三大整合策略

我国的网络安全产业已经发展了20余年,大大小小的企业几乎覆盖了网络安全的所有领域。随着安全需求的逐渐递增,安全产品也朝着平台化、规模化发展,这就倒逼着安全厂商需要整合越来越多的安全能力,并与其产品相融合。这个过程&#…

Kafka架构概述

Kafka的体系结构 Kafka是由Apache软件基金会管理的一个开源的分布式数据流处理平台。Kafka具有支持消息的发布/订阅模式、高吞吐量与低延迟、持久化、支持水平扩展、高可用性等特点。可以将Kafka应用于大数据实时处理、高性能数据管道、流分析、数据集成和关键任务应用等场景。…

【算法集训】基础算法:前缀和 | 概念篇

前缀和就是对于顺序表&#xff08;数组、列表&#xff09;来说&#xff0c;计算前面某一段元素的和。 1、部分和 给定一个数组&#xff0c;求某一段子数组的和。 2、朴素做法 int partialSum(int *a, int l, int r) {int i;int s 0;for(i l; i < r; i) {s a[i];}retu…

2020年吉林省玉米种植分布数据/作物分布数据

吉林省&#xff0c;位于中国东北中部&#xff0c;北接黑龙江省&#xff0c;南接辽宁省。东南部高&#xff0c;西北部低&#xff0c;中西部是广阔的平原。吉林省气候属温带季风气候&#xff0c;有比较明显的大陆性。吉林省素有“黑土地之乡”之称&#xff0c;土地肥沃&#xff0…

NMS 系列:soft,softer,weighted,iou-guided, Diou, Adaptive

系列文章目录 IOU 系列&#xff1a;IOU,GIOU,DIOU,CIOU 文章目录 系列文章目录一、NMS简介&#xff08;一&#xff09;为什么要使用NMS&#xff08;二&#xff09;NMS的算法流程&#xff08;三&#xff09;NMS的置信度重置函数&#xff08;四&#xff09;NMS的局限性&#xff…

【研究】光场相机测速技术中景深方向不确定性的改进方法

本项研究详细介绍了一种基于光场相机的粒子追踪测速&#xff08;PTV&#xff09;算法&#xff0c;旨在对三维速度场的三分量进行精细化测量。算法核心在于利用相机视角的多样性&#xff0c;辅以三角化测量和粒子追踪技术&#xff0c;有效优化了光场粒子图像测速&#xff08;PIV…

Linux——线程控制

目录 前言 一、线程创建 1.创建线程 2.线程传递结构体 3.创建多线程 4.收到信号的线程 二、线程终止 三、线程等待 四、线程分离 五、取消线程 六、线程库管理的原理 七、站在语言角度理解pthread库 八、线程的局部存储 前言 前面我们学习了线程概念和线程创建&…

异地文件如何共享访问?

异地文件共享访问是一种让不同地区的用户能够快速、安全地共享文件的解决方案。人们越来越需要在不同地点之间共享文件和数据。由于复杂的网络环境和安全性的问题&#xff0c;实现异地文件共享一直是一个挑战。 为了解决这个问题&#xff0c;许多公司和组织研发了各种异地文件共…

Spring Boot接收从前端传过来的数据常用方式以及处理的技巧

一、params 传参 参数是会拼接到url后面的请求 场景规范:url后面的key值<=3个参数的时候,使用params 传参 支持的请求方式:get(正规的是get方式)、post 都行 例如: http://localhost:8080/simpleParam?name=Tom&age=10 在postman里面的体现为 后端接收的接口…

20240402,<<,>>,控制流:while语句 ,for语句

……学很少&#xff0c;学很慢还是比不学强点是吧&#xff0c;救命 昨天不是很懂<<,>> 输入输出 iostream, 输入流 istream 输出流ostream&#xff0c;COUT,CIN,CERR,CLOG #include <iostream> int main() {std::cout << "enter two numbers:&…

成员变量、局部变量

变量分类 定义位置不同 成员变量定义在类中&#xff0c;成员方法之外 局部变量定义在局部范围内&#xff0c;如方法参数&#xff0c;方法内部&#xff0c;循环结构中等 作用范围不同&#xff08;空间&#xff09; 成员变量在整个类内有效&#xff0c;与声明位置无关 局部变…

图神经网络实战(7)——图卷积网络(Graph Convolutional Network, GCN)详解与实现

图神经网络实战&#xff08;7&#xff09;——图卷积网络详解与实现 前言1. 图卷积层2. 比较 GCN 和 GNN2.1 数据集分析2.2 实现 GCN 架构 小结系列链接 前言 图卷积网络 (Graph Convolutional Network, GCN) 架构由 Kipf 和 Welling 于 2017 年提出&#xff0c;其理念是创建一…