【嵌入式】C語言高級編程▁▁▁嵌入式C語言入門編程學習!

?? 1、C 語言標準

什么是 C 語言標準呢?

?????? 我們生活的現(xiàn)實世界,就是由各種標準構(gòu)成的,正是這些標準,我們的社會才會有條不紊的運行。

?????? 比如我們過馬路,遵循的交通規(guī)則就是一個標準:紅燈停,綠燈行,黃燈亮了等一等。當行人和司機都遵循這個默認的標準時,我們的交通系統(tǒng)才會順暢運行。

?????? 電腦中的 USB 接口也是一種標準,當大家生產(chǎn)的 USB 產(chǎn)品都遵循 USB 協(xié)議這種通信標準時,我們的手機、U 盤、USB 攝像頭、USB 網(wǎng)卡才可以在各種電腦設(shè)備上互插互拔。

?????? 2G、3G、4G 也是一種標準,當不同廠家生產(chǎn)的基帶芯片都遵循這種通信標準,我們所用的不同品牌、不同操作系統(tǒng)的手機才可能互相打電話、互相發(fā)微信、互相給對方點贊。

同樣,C 語言也有它自己的標準。

?????? 我們知道,C 語言程序需要通過編譯器,編譯生成二進制指令,才能在我們的電腦上運行。在 C 語言剛發(fā)布的早期,各大編譯器廠商開發(fā)自己的編譯器時,各自開發(fā),各自維護,時間久了,就會變得比較混亂。

?????? 這就會造成這樣一種局面:程序員寫的程序,在一個編譯器上編譯通過,在另一個編譯器編譯通不過。大家按各自的習慣來,誰也不服誰,就像春秋戰(zhàn)國時代:不同的貨幣、不同的度量衡,不同的文字,都是中國人,因為標準不統(tǒng)一,所以交流起來很麻煩,這樣下去也不是辦法啊。

?????? 后來 ANSI(AMERICAN NATIONAL STANDARDS INSTITUTE: 美國國家標準協(xié)會,簡稱 ANSI)出山了,聯(lián)合 ISO(國際化標準組織)召集各個編譯器廠商大佬,各種技術(shù)團體,一起喝個茶、開個碰頭會,開始啟動 C 語言的標準化工作。期間各種大佬之間也是矛盾重重,充滿各種爭議,但功夫不負有心人,經(jīng)過艱難的磋商,終于在1989年達成一致,發(fā)布了 C 語言標準,后來第二年又做了一些改進。于是,就像秦始皇統(tǒng)一六國、統(tǒng)一文字和度量衡一樣,C 語言標準終于問世了!因為是在 1989 年發(fā)布的,所以人們一般稱其為 C89 或 C90 標準,或者叫做ANSI C?。


?? 2、C 標準內(nèi)容

?????? C 標準英文文檔幾百頁,講了很多東西,但總體歸納起來,主要就是 C 語言編程的一些語法慣例,比如:

?? 定義各種關(guān)鍵字、數(shù)據(jù)類型

?? 定義各種運算規(guī)則

?? 各種運算符的優(yōu)先級和結(jié)合性

?? 數(shù)據(jù)類型轉(zhuǎn)換

?? 變量的作用域

?? 函數(shù)原型

?? 函數(shù)嵌套層數(shù)

?? 函數(shù)參數(shù)個數(shù)限制

?? 標準庫函數(shù)

?????? C 標準發(fā)布后,大家都遵守這個標準:程序員開發(fā)程序時,按照這種標準寫;編譯器廠商開發(fā)編譯器時,也按照這種標準去解析、翻譯程序。不同的編譯器廠商支持統(tǒng)一的標準,這樣大家寫的程序,使用不同的編譯器,都可以正確編譯、運行,大大提高程序的開發(fā)效率,推動了 IT 行業(yè)的發(fā)展。


?? 3、C 標準的發(fā)展歷程

?????? C 標準并不是永遠不變的,就跟移動通信一樣,也是從 2G、3G、4G 到 5G 不斷發(fā)展變化的。C 標準也經(jīng)歷了下面四個階段:

?? K&R C

?? ANSI C

?? C99

?? C11

?????? ☆? K&R C

?????? K&R C 一般也稱為傳統(tǒng) C。在 C 標準沒有統(tǒng)一之前,C 語言的作者 Dennis Ritchie 和 Brian Kernighan 合作寫了一本書《C 程序設(shè)計語言》。早期程序員編程,這本書可以說是絕對權(quán)威。這本書很薄,內(nèi)容精煉,主要介紹了 C 語言的基本使用方法。后來《C 程序設(shè)計語言》第二版問世,做了一些修改:比如新增 unsigned int、long int、struct 等數(shù)據(jù)類型;把運算符 =+/=- 修改為 +=/-=,避免運算符帶來的一些歧義和 Bug。這本書可以看作是 ANSI 標準的雛形。但早期的 C 語言還是很簡單的,比如還沒有定義標準庫函數(shù)、沒有預處理命令等。

?????? ☆? ANSI C

?????? ANSI C 是 ANSI(美國國家標準協(xié)會)在 K&R C 的基礎(chǔ)上,統(tǒng)一了各大編譯器廠商的不同標準,并對 C 語言語法和特性做了一些擴展,而發(fā)布的一個標準。這個標準一般也叫做 C89/C90,也是目前各種編譯器默認支持的 C 語言標準。ANSI C 主要新增了以下特性:

?? ●? 增加 signed、volatile、const 關(guān)鍵字

?? ●? 增加 void* 數(shù)據(jù)類型

?? ●? 增加預處理器命令

?? ●? 增加寬字符、寬字符串

?? ●? 定義了 C 標準庫

……

?????? ☆? C99 標準

C99 標準是 ANSI 1999 年在 C89 標準的基礎(chǔ)上新發(fā)布的一個標準,該標準對 ANSI C 標準做了一些擴充,比如新增一些關(guān)鍵字,支持新的數(shù)據(jù)類型:

?? ●? 布爾型:Bool

?? ●? 復數(shù):_Complex

?? ●? 虛數(shù):_Imaginary

?? ●? 內(nèi)聯(lián):inline

?? ●? 指針修飾符:restrict

?? ●? 支持long long、long double數(shù)據(jù)類型

?? ●? 支持變長數(shù)組

?? ●? 允許對結(jié)構(gòu)體特定成員賦值

?? ●? 支持16進制浮點數(shù)、float _Complex等數(shù)據(jù)類型

……

除此之外,C99 標準也借鑒其它語言的一些優(yōu)點,對語法和函數(shù)做了一系列改進,大大方便了程序員開發(fā)程序,比如:

?? ●? 變量聲明可以放代碼塊的任何地方。ANSI C 規(guī)定變量的聲明要全部寫在函數(shù)語句的最前面,否則就會報編譯錯誤。現(xiàn)在不需要這樣寫了,哪里需要使用變量,在哪里直接聲明使用即可;

?? ●? 源程序每行最大支持4095個字節(jié)。這個貌似足夠用了,沒有什么程序能復雜到一行程序有4KB個字符;

?? ●? 支持//單行注釋。ANSI C使用/**/沒有C++的//注釋方便,所以 C99 新標準借鑒過來了,也開始支持這種注釋方式;

?? ●? 標準庫新增了一些頭文件:如 stdbool.h、complex.h、stdarg.h、fenv.h 等。大家在 C 語言中經(jīng)常返回的 true、false,其實這也是 C++ 里面定義的 bool 類型。那為什么我們經(jīng)常這樣寫,而編器編譯程序時沒有報錯呢,這是因為早期大家編程使用的都是 VC++6.0 系列,是 C++ 編譯器。還有一種可能就是有些 IDE 對這個數(shù)據(jù)類型的數(shù)據(jù)做了封裝。

?????? ☆? C11 新標準

C11 標準是2011年發(fā)布的最新 C 語言標準,修改了 C 語言標準的一些 Bug、新增了一些特性:

?? ●? 增加 Noreturn,聲明函數(shù)無返回值;

?? ●? 增加Generic:支持泛型編程;

?? ●? 修改了標準庫函數(shù)的一些 Bug:如 gets( )函數(shù)被 gets_s() 函數(shù)代替;

?? ●? 新增文件鎖功能;

?? ●? 支持多線程;

……

?????? 從 C11 標準的修改內(nèi)容來看,也慢慢察覺到 C 語言未來的發(fā)展趨勢:

C 語言現(xiàn)在也在借鑒現(xiàn)在編程語言的優(yōu)點,不斷添加到自己的標準里面。比如現(xiàn)代編程語言的多線程、字符串、泛型編程等,C 語言最新的標準都支持。但是這樣下去,C 語言是不是還能保持她“簡單就是美”的優(yōu)雅特色呢,我們只能慢慢期待了。但至少目前我們不用擔心這些,因為 C11 新發(fā)布的標準,目前絕大多數(shù)編譯器還不支持,所以我們暫時還用不到。


?? 4、編譯器對 C 標準的支持

?????? 標準是一回事,各種編譯器支不支持是另一回事,這一點,大家要搞清楚。這就跟手機一樣,不同時期發(fā)布的手機對通信標準支持也不一樣。早期的手機可能只支持 2G 通信,后來支持 3G,現(xiàn)在發(fā)布的新款手機基本上都支持 4G了,而且可以兼容 2G/3G。

?????? 現(xiàn)在 5G 標準正在研發(fā),快發(fā)布了,據(jù)說 2019 年發(fā)布,2020 年商用。但是目前還沒有手機支持 5G 通信,就跟現(xiàn)在沒有編譯器支持 C11 標準一樣。

?????? 不同編譯器,甚至對 C 標準的支持也不一樣。有的編譯器只支持 ANSI C,這是目前默認的 C 標準。有的編譯器可以支持 C99,或者支持 C99 標準的部分特性。目前對 C99 標準支持最好的是 GNU C 編譯器,據(jù)說可以支持 C99標準99%的新增特性。


?? 5、編譯器對 C 標準的擴展

?????? 不同編譯器,出于開發(fā)環(huán)境、硬件平臺、性能優(yōu)化的需要,除了支持 C 標準外,還會自己做一些擴展。

?????? 在51單片機上用 C 語言開發(fā)程序,我們經(jīng)常使用 Keil for C51 集成開發(fā)環(huán)境。你會發(fā)現(xiàn) Keil for C51 或其他 IDE 里的 C 編譯器會對 C 語言標準作很多擴展。比如增加各種關(guān)鍵字:

?? ? data:RAM 的低128B空間,單周期直接尋址;

?? ? code:表示程序存儲區(qū);

?? ? bit:位變量,常用來定義單片機的 P0~P3 管腳;

?? ? sbit:特殊功能位變量;

?? ? sfr:特殊功能寄存器;

?? ? reentrant:重入函數(shù)聲明。

?????? 如果你在程序中使用以上這些關(guān)鍵字,那么你的程序就只能使用51編譯器來編譯運行,你使用其它的編譯器,比如 VC++6.0,是編譯通不過的。

?????? 同樣的道理,GCC 編譯器,也對 C 標準做了很多擴展:

?? ? 零長度數(shù)組

?? ? 語句表達式

?? ? 內(nèi)建函數(shù)

?? ? __attribute__特殊屬性聲明

?? ? 標號元素

?? ? case 范圍

?????? 比如支持零長度數(shù)組。這些新增的特性,C 標準目前是不支持的,其它編譯器也不支持。如果你在程序中定義一個零長度數(shù)組:

????? 編譯如下:

?????? 只能使用 GCC 編譯器才能正確編譯,使用 VC++ 6.0編譯器編譯可能就通不過,因為微軟的 C++ 編譯器不支持這個特性。


?? 6、Linux內(nèi)核C語言示例

?????? 大家在看一些 GNU 開源軟件,或者閱讀 Linux 內(nèi)核、驅(qū)動源碼時會發(fā)現(xiàn),在 Linux 內(nèi)核源碼中,有大量的 C 程序看起來“怪怪的”。甚至有些都看不懂。

宏定義

內(nèi)核中實現(xiàn)打印功能的宏定義

結(jié)構(gòu)體初始化

?????? 這些其實也是 C 語言,但并不是標準的 C 語言語法?,而是我們 Linux 內(nèi)核使用的 GNU C 編譯器擴展的一些 C 語言語法。這些語法在 C 語言教材或資料中一般不會提及,所以你才會似曾相識而又感到陌生,看起來感覺“怪怪的”。

????? 我們在做 Linux 驅(qū)動開發(fā),或者閱讀 Linux 內(nèi)核源碼過程中,會經(jīng)常遇到這些“稀奇古怪”的用法,如果不去了解這些特殊語法的具體含義,可能就對代碼的理解造成一定障礙。


????? 今天的分享就到這里嘍,消化一下!希望你能讓知識停留在你腦子里一輩子,而不是一下子!

學C/C++不易,此路應攜手前行。

歡迎關(guān)注我的編程公眾號【草莓味貍貓】!?

如果你想跟著小編一起學編程的話!

可以來我的C語言C++編程學習基地,【點擊進入】!

還有(源碼,零基礎(chǔ)教程,項目實戰(zhàn)教學視頻)!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內(nèi)容