日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【嵌入式】C语言高级编程-嵌入式C语言简介(01)

發(fā)布時(shí)間:2024/4/24 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【嵌入式】C语言高级编程-嵌入式C语言简介(01) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

00. 目錄

文章目錄

    • 00. 目錄
    • 01. C 語言標(biāo)準(zhǔn)
    • 02. C 標(biāo)準(zhǔn)內(nèi)容
    • 03. C 標(biāo)準(zhǔn)的發(fā)展歷程
    • 04. 編譯器對 C 標(biāo)準(zhǔn)的支持
    • 05. 編譯器對 C 標(biāo)準(zhǔn)的擴(kuò)展
    • 06. Linux內(nèi)核C語言示例
    • 07. 附錄

01. C 語言標(biāo)準(zhǔn)

什么是 C 語言標(biāo)準(zhǔn)呢?我們生活的現(xiàn)實(shí)世界,就是由各種標(biāo)準(zhǔn)構(gòu)成的,正是這些標(biāo)準(zhǔn),我們的社會才會有條不紊的運(yùn)行。比如我們過馬路,遵循的交通規(guī)則就是一個(gè)標(biāo)準(zhǔn):紅燈停,綠燈行,黃燈亮了等一等。當(dāng)行人和司機(jī)都遵循這個(gè)默認(rèn)的標(biāo)準(zhǔn)時(shí),我們的交通系統(tǒng)才會順暢運(yùn)行。電腦中的 USB 接口也是一種標(biāo)準(zhǔn),當(dāng)大家生產(chǎn)的 USB 產(chǎn)品都遵循 USB 協(xié)議這種通信標(biāo)準(zhǔn)時(shí),我們的手機(jī)、U 盤、USB 攝像頭、USB 網(wǎng)卡才可以在各種電腦設(shè)備上互插互拔。2G、3G、4G 也是一種標(biāo)準(zhǔn),當(dāng)不同廠家生產(chǎn)的基帶芯片都遵循這種通信標(biāo)準(zhǔn),我們所用的不同品牌、不同操作系統(tǒng)的手機(jī)才可能互相打電話、互相發(fā)微信、互相給對方點(diǎn)贊。

同樣,C 語言也有它自己的標(biāo)準(zhǔn)。我們知道,C 語言程序需要通過編譯器,編譯生成二進(jìn)制指令,才能在我們的電腦上運(yùn)行。在 C 語言剛發(fā)布的早期,各大編譯器廠商開發(fā)自己的編譯器時(shí),各自開發(fā),各自維護(hù),時(shí)間久了,就會變得比較混亂。這就會造成這樣一種局面:程序員寫的程序,在一個(gè)編譯器上編譯通過,在另一個(gè)編譯器編譯通不過。大家按各自的習(xí)慣來,誰也不服誰,就像春秋戰(zhàn)國時(shí)代:不同的貨幣、不同的度量衡,不同的文字,都是中國人,因?yàn)闃?biāo)準(zhǔn)不統(tǒng)一,所以交流起來很麻煩,這樣下去也不是辦法啊。

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

02. C 標(biāo)準(zhǔn)內(nèi)容

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

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

  • 定義各種運(yùn)算規(guī)則

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

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

  • 變量的作用域

  • 函數(shù)原型

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

  • 函數(shù)參數(shù)個(gè)數(shù)限制

  • 標(biāo)準(zhǔn)庫函數(shù)

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

03. C 標(biāo)準(zhǔn)的發(fā)展歷程

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

  • K&R C

  • ANSI C

  • C99

  • C11

K&R C

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

ANSI C

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

  • 增加 signed、volatile、const 關(guān)鍵字
  • 增加 void* 數(shù)據(jù)類型
  • 增加預(yù)處理器命令
  • 增加寬字符、寬字符串
  • 定義了 C 標(biāo)準(zhǔn)庫
  • ……

C99 標(biāo)準(zhǔn)

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

  • 布爾型:Bool
  • 復(fù)數(shù):_Complex
  • 虛數(shù):_Imaginary
  • 內(nèi)聯(lián):inline
  • 指針修飾符:restrict
  • 支持long long、long double數(shù)據(jù)類型
  • 支持變長數(shù)組
  • 允許對結(jié)構(gòu)體特定成員賦值
  • 支持16進(jìn)制浮點(diǎn)數(shù)、float _Complex等數(shù)據(jù)類型
  • ……

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

  • 變量聲明可以放代碼塊的任何地方。ANSI C 規(guī)定變量的聲明要全部寫在函數(shù)語句的最前面,否則就會報(bào)編譯錯(cuò)誤。現(xiàn)在不需要這樣寫了,哪里需要使用變量,在哪里直接聲明使用即可;
  • 源程序每行最大支持4095個(gè)字節(jié)。這個(gè)貌似足夠用了,沒有什么程序能復(fù)雜到一行程序有4KB個(gè)字符;
  • 支持//單行注釋。ANSI C使用/**/沒有C++的//注釋方便,所以 C99 新標(biāo)準(zhǔn)借鑒過來了,也開始支持這種注釋方式;
  • 標(biāo)準(zhǔn)庫新增了一些頭文件:如 stdbool.h、complex.h、stdarg.h、fenv.h 等。大家在 C 語言中經(jīng)常返回的 true、false,其實(shí)這也是 C++ 里面定義的 bool 類型。那為什么我們經(jīng)常這樣寫,而編器編譯程序時(shí)沒有報(bào)錯(cuò)呢,這是因?yàn)樵缙诖蠹揖幊淌褂玫亩际?VC++6.0 系列,是 C++ 編譯器。還有一種可能就是有些 IDE 對這個(gè)數(shù)據(jù)類型的數(shù)據(jù)做了封裝。

C11 新標(biāo)準(zhǔn)

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

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

  • 增加Generic:支持泛型編程;

  • 修改了標(biāo)準(zhǔn)庫函數(shù)的一些 Bug:如 gets( )函數(shù)被 gets_s() 函數(shù)代替;

  • 新增文件鎖功能;

  • 支持多線程;

  • ……

從 C11 標(biāo)準(zhǔn)的修改內(nèi)容來看,也慢慢察覺到 C 語言未來的發(fā)展趨勢:C 語言現(xiàn)在也在借鑒現(xiàn)在編程語言的優(yōu)點(diǎn),不斷添加到自己的標(biāo)準(zhǔn)里面。比如現(xiàn)代編程語言的多線程、字符串、泛型編程等,C 語言最新的標(biāo)準(zhǔn)都支持。但是這樣下去,C 語言是不是還能保持她“簡單就是美”的優(yōu)雅特色呢,我們只能慢慢期待了。但至少目前我們不用擔(dān)心這些,因?yàn)?C11 新發(fā)布的標(biāo)準(zhǔn),目前絕大多數(shù)編譯器還不支持,所以我們暫時(shí)還用不到。

04. 編譯器對 C 標(biāo)準(zhǔn)的支持

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

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

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

05. 編譯器對 C 標(biāo)準(zhǔn)的擴(kuò)展

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

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

  • data:RAM 的低128B空間,單周期直接尋址;
  • code:表示程序存儲區(qū);
  • bit:位變量,常用來定義單片機(jī)的 P0~P3 管腳;
  • sbit:特殊功能位變量;
  • sfr:特殊功能寄存器;
  • reentrant:重入函數(shù)聲明。

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

同樣的道理,GCC 編譯器,也對 C 標(biāo)準(zhǔn)做了很多擴(kuò)展:

  • 零長度數(shù)組
  • 語句表達(dá)式
  • 內(nèi)建函數(shù)
  • __attribute__特殊屬性聲明
  • 標(biāo)號元素
  • case 范圍

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

#include <stdio.h>int main(void) {int a[0];return 0; }

編譯如下:

deng@itcast:~/tmp$ gcc 1test.c -Wall -o test deng@itcast:~/tmp$ ./test a = 0x7ffc8235f974 deng@itcast:~/tmp$

只能使用 GCC 編譯器才能正確編譯,使用 VC++ 6.0編譯器編譯可能就通不過,因?yàn)槲④浀?C++ 編譯器不支持這個(gè)特性。

06. Linux內(nèi)核C語言示例

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

宏定義

linux-headers-5.4.0-33/include/linux/kernel.h

/** The double __builtin_constant_p is because gcc will give us an error* if we try to allocate the static variable to fmt if it is not a* constant. Even with the outer if statement.*/ #define ftrace_vprintk(fmt, vargs) \ do { \if (__builtin_constant_p(fmt)) { \static const char *trace_printk_fmt __used \__attribute__((section("__trace_printk_fmt"))) = \__builtin_constant_p(fmt) ? fmt : NULL; \\__ftrace_vbprintk(_THIS_IP_, trace_printk_fmt, vargs); \} else \__ftrace_vprintk(_THIS_IP_, fmt, vargs); \ } while (0)

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

/** Like KERN_CONT, pr_cont() should only be used when continuing* a line with no newline ('\n') enclosed. Otherwise it defaults* back to KERN_DEFAULT.*/ #define pr_cont(fmt, ...) \printk(KERN_CONT fmt, ##__VA_ARGS__)

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

linux-4.16.12/net/bluetooth/6lowpan.c

static const struct file_operations lowpan_control_fops = {.open = lowpan_control_open,.read = seq_read,.write = lowpan_control_write,.llseek = seq_lseek,.release = single_release, };

這些其實(shí)也是 C 語言,但并不是標(biāo)準(zhǔn)的 C 語言語法,而是我們 Linux 內(nèi)核使用的 GNU C 編譯器擴(kuò)展的一些 C 語言語法。這些語法在 C 語言教材或資料中一般不會提及,所以你才會似曾相識而又感到陌生,看起來感覺“怪怪的”。我們在做 Linux 驅(qū)動(dòng)開發(fā),或者閱讀 Linux 內(nèi)核源碼過程中,會經(jīng)常遇到這些“稀奇古怪”的用法,如果不去了解這些特殊語法的具體含義,可能就對代碼的理解造成一定障礙。

接下來就是帶領(lǐng)大家一起去了解 Linux 內(nèi)核或者 GNU 開源軟件中,常用的一些 C 語言特殊語法擴(kuò)展,掃除閱讀 Linux 內(nèi)核或 GNU 開源軟件時(shí),這些擴(kuò)展特性帶給我們的語法閱讀障礙和困惑。

07. 附錄

7.1 Linux內(nèi)核官方

網(wǎng)址:https://www.kernel.org/

7.2 參考資料
C語言嵌入式Linux高級編程

7.3 GNU C語法擴(kuò)展大全
網(wǎng)址:http://tigcc.ticalc.org/doc/gnuexts.html

7.4 GCC參考手冊
網(wǎng)址:https://gcc.gnu.org/onlinedocs/gcc/

總結(jié)

以上是生活随笔為你收集整理的【嵌入式】C语言高级编程-嵌入式C语言简介(01)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。