C語言是一種通用、面向過程的編程語言,具有高效、簡潔、靈活等特點,被廣泛應用于各個領域的軟件開發和系統編程。具體來說,它是一種命令式過程語言,支持結構化編程、詞法變量作用域和遞歸,具有靜態類型系統。從設計上講,C語言的設計目標是提供足夠高級的抽象和結構,接近底層硬件的控制。這使得C語言非常適合于系統級編程和底層開發,能夠直接訪問硬件資源,并具有高效的性能。C語言常用于從最大的超級計算機到最小的微控制器和嵌入式系統等各種計算機架構。
C語言是編程B語言的后繼語言,最初由丹尼斯·里奇于1972年至1973年在貝爾實驗室開發,用于構建在Unix上運行的實用程序。1978年 ,由C語言原設計者合著的《C程序設計語言(The C Programming Language)》一書問世,隨后C語言開始廣泛使用,該書也是C語言的首要參考語言規范。在20世紀80年代,C語言逐漸流行起來,并由美國國家標準學會(ANSI C)和國際標準化組織(ISO)主要負責對C語言的標準化。時至21世紀,它已成為使用最廣泛的編程語言之一,幾乎所有現代計算機架構和操作系統都有C編譯器可用。
一個遵循標準的C程序,有高可移植性,僅需少量修改,就可在多種計算機平臺和操作系統上進行編譯。此外,C語言具有簡單的語法和豐富的庫函數,為程序員提供了廣泛的功能和靈活的編程方式。
自1988年以來,C語言在衡量編程語言受歡迎程度的TIOBE指數排名中保持在前兩位。
概述
C語言是一種通用的、面向過程式的計算機編程語言,與大多數ALGOL族(ALGOrithmic Language,指令式編程語言族)的大多數過程式編程語言類似。和C++、c#、Java等面向對象編程語言有所不同的是,C語言的設計目標是提供一種能以簡易的方式編譯、處理低級存儲器、僅產生少量的機器碼以及不需要任何運行環境支持便能運行的編程語言。C語言描述問題比匯編語言迅速、工作量小、可讀性好、易于調試、修改和移植,一般只比匯編語言代碼生成的目標程序效率低10%-20%,而代碼質量與匯編語言相當。因此,C語言十分適用于編寫系統級軟件。
從設計細節中來說,C語言采用靜態類型系統和有結構化程序設計的特性,具有變量作用域和遞歸功能。C語言中的可執行代碼包含在子程序(函數)中,其函數參數大多采用值傳遞方式,而數組等特殊數據結構則通過傳遞指針(指向數組第一個元素的地址)來傳遞。
C語言還具有以下的特性:
1.基本數據類型包括字符、整型和浮點數等,還有指針、數組、結構等派生數據類型、void類型和枚舉類型。
2.變量類型可以轉換,如整數型和字符型變量。
3.可以通過指針對存儲器進行低級控制。
4.不同的變量類型可以組合在一起形成結構體。
5.支持基本的控制流,如條件判斷、循環等。
6.函數可以返回各種數據類型的值,并且可以遞歸調用。
7.C語言目前有44個保留字,允許靈活的變量和函數命名。
8.編譯預處理機制增強了C語言的靈活性。
歷史演進
C語言的起源和創造者
C語言最早由丹尼斯·里奇(Dennis Ritchie)為了在PDP-11電腦上運行的unix系統所設計出來的編程語言,初次發展在1969年到1973年之間。其起源也與Unix操作系統的開發密切相關。它源于BCPL語言,后者由馬丁·理察德(Martin Richards)于1967年左右設計實現。
1969年,PDP-7是貝爾實驗室內可用的計算機之一,它是一臺由迪吉多(Digital Equipment Corporation)生產的小型計算機。在項目初期,實驗室人員選擇一臺已經可用的計算機進行開發可能會更加方便,而不需要額外的投資和配置。當時,PDP-7上運行的操作系統很有限,而實驗需要更強大的操作系統。所以肯·湯普遜(Ken Thompson)和里奇等人在貝爾實驗室開始了一個項目,目標是為PDP-7開發一個更強大和通用的操作系統。這個項目的成果就是UNICS(Uniplexed Information and Computing Service),它奠定了后來unix操作系統的基礎,為計算機領域帶來了重大影響,也被稱作第一版UNIX。
開發操作系統后,肯希望有一種編程語言來為該平臺開發實用程序。1970年,為運行在PDP-7上的首個Unix系統創建了一個最新開發的BCPL系統編程語言的精簡版本,被稱為B語言。因為PDP-7的性能不佳,肯·湯普遜與丹尼斯·里奇決定把第一版UNIX移植到PDP-11/20的機器上,開發第二版UNIX。但是由于B語言的速度太慢,而且無法利用PDP-11的字節尋址能力等特性,最終用B語言編寫的實用程序寥寥無幾。
PDP-11出世后,貝爾實驗室也升級了設備,用PDP-11代替了PDP-7。為了利用功能更強大的PDP-11的特性,1971年丹尼斯開始改進B語言。一個新增的重要功能是字符數據類型,他稱之為新B語言(NB)。與此同時,肯開始使用NB語言編寫Unix內核,并決定了NB語言的發展方向,有了int和char數組。此外,還增加了指針、生成指向其他類型的指針的能力、所有類型的數組以及從函數返回的類型。表達式中的數組變成了指針,并編寫了新的編譯器,語言也更名為C語言。自此,C語言正式問世,C語言編譯器和一些實用程序也被收錄到第二版Unix(也被稱為Research Unix)中。
1973年左右,C語言預處理器被引入第四版Unix,這是C語言第一次應用在操作系統的核心編寫上。此時,C語言已經具備了一些強大的功能,如結構類型(struct)。預處理器的最初版本只提供了包含文件和簡單的字符串替換:無參數宏的#include和#define。此后不久,邁克·萊斯克(Mike Lesk)和約翰·雷澤(John Reiser)等人對其進行了擴展開發,納入了帶參數和條件編譯的宏。1975年起,C語言開始移植到其他機器上使用,從那時起,C在大多數計算機上被使用,從最小的微型計算機到與CRAY-2超級計算機。當時的C語言很規范,即使沒有一份正式的標準,人們也可以寫出C程序,并且無須修改就可以運行在任何支持C語言和最小運行時環境的計算機上。
發展歷程
基本要素
字符集
基本的C源字符集包括以下字符:
其中,換行表示文本行的結束,它不一定要對應于一個實際的單個字符,但是為了方便起見,C將其視為一個字符。多字節編碼字符可以在字符串文字中使用,但它們不是完全可移植的。基本的C執行字符集包含相同的字符,以及警報、退格和回車等表示,每版C標準修訂版都增加了關于擴展字符集的支持。
關鍵字
截至C11,有44個關鍵字,也稱為保留字,這些關鍵字是預定義的,除了它們預定用途之外,不能被用于的任何其他目的:
C23將添加14個關鍵字,并將以前定義一些關鍵字成為備選關鍵字,包括:_Alignas、_Alignof、_Bool、_Static_assert、_Thread_local。
操作符
C語言支持豐富的運算符集,這些運算符是在表達式中使用的符號,用于指定在計算該表達式時要執行的操作。
變量和數據類型
C語言是一種靜態類型的編程語言,它要求在使用變量之前必須先聲明變量的數據類型。變量是用于存儲和操作數據的一種基本概念,而數據類型則決定了變量可以存儲的數據的種類和范圍。數據類型構成了數據元素存儲的語義和特征,它們在語言語法中以內存位置或變量聲明的形式表達。數據類型還決定了數據元素的操作類型或處理方法。為便于理解,可以將數據類型粗略的分為基本數據類型,枚舉類型,void類型、枚舉類型和派生類型,這些類型基本可以涵蓋C語言常用數據類型。但在ISO標準里,還可以有其他歸類方式,如算術類型和指針類型統稱為標量類型;數組和結構類型統稱為聚合類型;數組、函數和指針類型統稱為派生聲明器類型等等。
基本數據類型
算數類型
C語言提供了int、float和double三種基本數據算數類型(arithmetic types)說明符,以及有符號、無符號、短和長等修飾符。下表列出了在指定特定存儲大小聲明時允許的組合。
整數類型的實際大小因實現而異,標準C僅要求數據類型之間的大小關系,以及每個數據類型的最小大小,具體關系要求是:
int類型應該是目標處理器效率最高的整數類型,提供了很大的靈活性。在實際應用中,char通常是8位大小,short通常是16位大小(無符號類型也是如此)。這對于多數平臺都成立,例如1990年代的SunOS 4 Unix、微軟 MS-DOS、現代Linux以及Microchip MCC18用于嵌入式8位PIC微控制器。浮點類型(float)的實際大小和行為也因實現而異。唯一的要求是long double不得小于double,double不得小于float。
非算數類型
字符類型
值得注意的是,由于char的大小始終是最小支持的數據類型,因此除了位字段之外,其他數據類型不能更小,所以char的最小大小為8位。POSIX要求char的大小也為8位。標準C中的各種規則使得unsigned char成為用于存儲任意非位字段對象的數組的基本類型。
布爾類型
C99增加了布爾(True/False)類型“_Bool”。此外,
如果unsigned char的大小為8位,變量b的值將為false。這是因為值256不適配布爾數據類型,導致只有它的低8位被使用,從而產生一個零值。不過,改變類型后,之前的代碼就會正常運行:
“_Bool”類型還能確保真值之間恒相等:
void 類型
void類型表示沒有值的數據類型,通常用于函數返回值。它通常用于以下三種情況下:
枚舉類型
枚舉(Enumerated)用于定義一組具有離散值的常量,它可以讓數據更簡潔,更易讀。枚舉類型通常用于為程序中的一組相關的常量取名字,以便于程序的可讀性和維護性。定義一個枚舉類型,需要使用enum關鍵字,后面跟著枚舉類型的名稱,以及用大括號{}括起來的一組枚舉常量。每個枚舉常量可以用一個標識符來表示,也可以為它們指定一個整數值,如果沒有指定,那么默認從0開始遞增。它在C語言實現中是以int類型儲存的。舉個例子:
派生類型
C語言允許構造出任意數量的派生類型。這些成員可以是任意對象或函數類型。C語言中的聚合數據類型有六種:數組類型、指針類型、結構體類型、聯合類型、函數類型和原子類型。
數組類型
數組(Arrays)是相同類型的值的集合,在內存中連續存儲。除void和函數類型外,每種類型T都可以存在"由N個類型元素組成的數組"類型,即該類型數組。大小為N的數組由從0到N-1(包括N-1)的整數索引。
下面是一個簡單的例子:
數組可以多維初始化,但不能多維賦值。
數組將指向第一個元素的指針傳遞給函數。多維數組的定義為數組的數組,除了最外層維度之外,所有維度定義時都必須確定常量大小:
指針類型
指針(Pointers)是一種數據類型,它存儲了特定類型變量的內存地址。對于每一種數據類型T,都存在與之對應的指向T類型的指針類型。在進行類型聲明時,需要在變量名之前加上一個星號(*)來聲明指針類型,而這個星號前后的空格是可選的。星號告訴編譯器正在聲明一個指針,而不是一個普通的變量。指針的值是一個內存地址,它指向了存儲在內存中的特定類型的數據。
也可以為指針數據類型聲明指針,從而創建多個間接指針,如char**和int***,包括數組類型的指針。后者不如數組指針常見,其語法也比較容易混淆:
元素pc是個數組元素,包含10個指針元素,每個指針元素的大小是指針類型的大小(在大多數平臺上通常是4或8字節),與指向char的指針類型大小無關。元素pa是一個指向數組的指針,所以pa的大小即一個char類型等大小,即4或8字節;而*pa 是一個指向數組的指針,指向一個有10個char元素的數組,所以其大小是數組的大小,為10字節。
結構體類型
結構體(Structures)將多個可能具有不同數據類型的數據項的存儲匯集到一個由單個變量引用的內存塊中。以下示例聲明了數據類型struct birthday,其中包含了一個人的姓名和生日。結構體定義后,是對變量John的聲明,該變量分配了所需的存儲空間。
結構體的內存布局是由每個平臺的語言實現決定的,但有一些限制:第一個成員的內存地址必須與結構體本身的地址相同;可以使用復合字面量來初始化或分配結構體。函數可以直接返回一個結構體,但是這種方式在運行時通常不太高效。自C99以來,結構體最后一個成員也可以是柔性數組。實際運用中,還常常使用包含指向自身類型的結構體指針的結構體來構建鏈式數據結構:
聯合類型
聯合類型(Unions)是一種特殊的構造,允許使用不同類型的來訪問同一內存塊。例如,可以聲明一個數據類型的聯合,以允許將相同的數據讀取為整數、浮點數或任何其他用戶聲明的類型。在下面的示例代碼中,聯合u的總大小是u.s的大小——這恰好是u.s.u和u.s.d大小的總和,而且s大于i和f。當將某個值賦給u.i,如果u.i小于u.f,則可能會保留u.f的某些部分。值得注意的是,從聯合中讀取成員與強制轉換不同,因為成員的值不會被轉換,只是被讀取。聯合類型不被認為是聚合類型,因為在任一時刻下,聯合中只有一個成員可以具有值。
函數類型
函數類型(Functions)是指返回類型已指定的函數,其特征由返回類型和參數的數量、類型決定。如果函數的返回類型是T,它就被稱為“返回T的函數”。函數類型實際上定義了指向函數的指針,函數指針存儲函數的入口地址,類似于其他指針存儲的內存單元中的地址值。如下面的例子:
其中,say_hello是一種函數類型,而函數類型和數組類型類似,做右值使用時自動轉換成函數指針類型,所以可以直接賦給f,當然也可以寫成void (*f)(const char *) = &say_hello;,把函數say_hello先取地址再賦給f,就不需要自動類型轉換了。關于函數的進一步說明,請查看核心編程概念與技術章節。
原子類型
原子類型(Atomic)是由_Atomic指定的類型。原子類型是一種條件特性,出現 _Atomic 限定符就表示原子類型。原子類型說明符使用方法如下:
值得注意的是,與原子類型相關的屬性只對左值表達式有意義。如果_Atomic關鍵字后面緊跟一個左括號,那它將被認為是一個類型指定符,而不是一個類型限定符。
語句和語塊
C語言的語句和塊是構建程序的基本單元。語句是一系列指令或操作,用于執行特定的任務。語法結構規定了如何組織和編寫這些語句,以便創建有效的C程序。塊允許將多個語句組織在一起,形成一個邏輯單元,從而使代碼更加清晰和可讀。在C語言中,語句和塊的組合方式構成了程序的結構和邏輯流程,允許程序員實現各種功能和操作。通過合理地使用不同類型的語句和塊,可以構建出高效、清晰和功能完備的C程序。
語句
在C語言中,語句(Statement)是編程中的基本構建塊,它代表了一種執行動作或操作的指令。C語言中的每條語句以分號“;”結束。語句可以是簡單的表達式、賦值、函數調用,也可以是控制流語句,如條件語句和循環語句。簡單的語句類型包括:
此外還有控制流語句,用于控制程序的執行流程,使程序能夠根據條件或循環來做出不同的決策。所以他可以影響程序的執行流程,包括條件語句(if、else)、循環語句(for、while、do-while)等。
條件語句
if語句
if語句包括判斷指定一個或多個要評估或測試的條件,條件為真時要執行的語句(必需的)和條件為假時要執行的語句(可選的)。注意,C 語言把任何非零和非空的值假定為 true,把零或 null 假定為 false。
以下是一個if語句的代碼示例
條件運算符 ? :,可以用來替代 if...else 語句。它的一般形式如下:
switch語句
一個 switch 語句允許測試一個變量等于多個值時的情況。每個值稱為一個 case,且被測試的變量會對每個 switch case 進行檢查。
switch代碼示例如下:
循環語句
有的時候,可能需要多次執行同一塊代碼。C語言提供了兩種主要的循環語句,用于重復執行一段代碼塊,直到滿足特定條件為止,這些循環語句是:for 循環、while 、do-while 循環。
for語句
for循環是一種常用的循環控制結構,它允許編寫一個在滿足條件的情況下重復執行的循環。
示例代碼如下:
該代碼中 for 循環的控制流是:init 會首先被執行,且只會執行一次。這一步允許聲明并初始化任何循環控制變量,或者可以不在這里寫任何語句,只要有一個分號出現即可。接下來,會判斷 condition:如果為真,則執行循環主體;如果為假,則不執行循環主體,且控制流會跳轉到緊接著 for 循環的下一條語句。在執行完 for 循環主體后,控制流會跳回的 increment 語句。該語句允許更新循環控制變量,此處也可以留空,只要在條件后有一個分號出現即可。然后條件再次被判斷。如果為真,則執行循環,這個過程會不斷重復,直到在條件變為假時,for 循環終止。
while語句
只要給定的條件為真,C 語言中的 while 循環語句會重復執行一個目標語句。在這里,被循環的可以是一個單獨的語句,也可以是幾個語句組成的代碼塊。執行條件可以是任意的表達式,該條件當為任意非零值時都為 true。當條件為 true 時執行循環。 當條件為 false 時,退出循環,程序流將繼續執行緊接著循環的下一條語句。
示例代碼如下:
do-while語句
和for 和 while 循環不同,它們是在循環頭部測試循環條件。在 C 語言中,do-while 循環是在循環的尾部檢查它的條件。do-while 循環與 while 循環類似,但是 do-while 循環會確保至少執行一次循環。
示例代碼如下:
語塊
語塊(Block)是由一組語句組成的代碼段,用花括號“{ }”括起來。語塊可以包含多條語句,將它們作為一個邏輯單元組織在一起。在C語言中,塊通常用于構建函數體、條件分支和循環體等。它有以下特點:
在下面的示例中,if語句和內部的語塊都展示了塊的使用。語塊有助于組織代碼、限定變量作用域,并在控制流結構中提供更大的靈活性。
核心編程概念與技術
良好的編程技術是構建可維護、高效和靈活的軟件系統的基石,此處主要介紹函數與模塊化以及內存管理這兩個關鍵方面。C語言的模塊化和函數、以及內存管理能力賦予了開發者更大的靈活性和控制權,同時也要求開發者具備良好的編程實踐和責任感,以確保程序的正確性和穩定性。代碼組織結構上來說,模塊化即功能細化,可以使邏輯更清晰,可讀性更好,維護成本低;底層邏輯看,內存管理是組織存儲數據和運算的最基本手段,不好的內存管理常常會導致產品崩潰,數據被盜等等問題。
函數與模塊化
函數與模塊化是程序設計的基本構建塊,強調將復雜問題分解為更小、更易管理的部分。通過函數,我們能夠將代碼邏輯封裝成獨立的、可重用的單元,從而提高了代碼的可讀性、可維護性和可測試性。模塊化則進一步將函數組織為模塊,每個模塊有特定的功能,模塊之間通過接口交互。這種結構化的方法使得開發者能夠專注于解決特定問題,同時也促進了團隊協作和代碼復用。
在函數方面,C語言允許開發者定義自己的函數,通過函數名和參數列表來調用這些函數。函數可以接受參數,執行一系列操作,然后返回一個值。這樣的抽象使得開發者可以將代碼邏輯封裝起來,只需要關注函數的輸入和輸出。模塊化編程則進一步擴展了這種思想,將函數分組為模塊,每個模塊可以包含多個函數。每個模塊都有特定的功能,模塊之間通過接口進行通信。這種分解使得程序更加模塊化,每個模塊都可以獨立開發和測試,最終組合在一起形成完整的程序。
函數的使用
在C語言中,函數是一個執行特定任務的代碼塊,它能夠接受輸入參數、執行操作,并返回一個值。下面是關于函數的定義和聲明的詳細說明:
函數定義
C 語言中的函數定義的一般形式如下:
函數聲明
函數聲明是指提前告知編譯器有一個函數存在,但并不提供函數的實際實現。這在多個文件中使用同一個函數時非常有用,編譯器在鏈接時會找到實際的函數定義。函數聲明包括返回類型,函數名和參數列表,比如:
函數調用
函數調用是指在程序中使用函數來執行特定任務。調用函數涉及以下步驟:
1. 調用函數:通過函數名和參數列表調用函數。例如:result = add(5, 3);
2. 傳遞參數:將實際參數傳遞給函數。函數的參數可以是值、指針、數組等。
3. 執行函數:函數體中的代碼將根據傳遞的參數執行操作。
4. 返回值:函數執行后,可以通過`return`語句將結果返回給調用者。
其調用的語法為:
其中:
舉個例子:
請注意,函數調用的實際參數必須與函數聲明中的參數類型和順序匹配。調用函數時,實際參數會被傳遞給函數的形式參數(在函數定義中使用的參數),函數內部將使用這些形式參數執行相應的操作。函數調用的結果(返回值)可以被賦值給變量或用于其他計算。如果函數沒有返回值(返回類型為 void),則函數調用只需要函數名和實際參數列表,不需要將結果賦給變量。
模塊化編程
模塊化編程是一種將大型程序分解為更小、更易管理的模塊的方法。每個模塊負責特定的任務,使代碼更加組織化、可讀性更強、可維護性更高。模塊化編程強調以下幾點:
模塊化編程可以減少代碼的復雜性,便于團隊協作,允許并行開發,以及更容易進行調試和維護。
內存管理
內存管理是確保程序正確、高效地使用計算機內存資源的關鍵。它涉及到動態內存分配和釋放,以及避免內存泄漏和越界訪問等問題。通過合理地分配和釋放內存,程序可以有效地利用計算機的內存資源,降低資源浪費。同時,內存管理也需要開發者理解指針的概念和用法,以確保數據在內存中正確存儲和訪問。C語言提供了兩主要的方式來為對象分配內存,即靜態內存管理理和動態內存管理。
靜態內存管理
靜態內存管理是指在編譯時為變量和數據分配固定大小的內存空間。在C語言中,全局變量和局部靜態變量都使用靜態內存分配。這些變量的內存分配在程序啟動時就完成,其生命周期與整個程序運行周期相同。靜態內存分配發生在編譯時,變量在程序生命周期內占據固定的內存位置。它適用于需要在整個程序中保持數據的情況,如配置參數、常量等。此外靜態內存分配的空間較小,所以不適合存儲大量數據或動態變化的數據。
動態內存分配
動態內存管理是指在程序運行時根據需要分配和釋放內存空間。動態內存分配允許在運行時根據具體情況分配所需大小的內存塊,但需要手動釋放分配的內存,以避免內存泄漏。它適用于需要在程序運行期間根據需求分配和釋放內存的情況,如動態數組、鏈表、字符串等。而且內存分配的大小可以根據需求動態變化,但需要手動管理內存的釋放,以防止內存泄漏。在使用動態內存管理時,要謹慎處理內存釋放,以免產生懸掛指針或野指針等問題。在C語言中,可以使用標準庫函數malloc和free來實現動態內存分配和釋放。
標準庫函數
C語言使用庫作為其主要的擴展方法。在C語言中,庫是一組包含在單個“存檔”文件中的函數。每個庫通常都有一個頭文件,其中包含庫中包含的函數的原型,并聲明了與這些函數一起使用的特殊數據類型和宏符號。如果程序想要使用庫,必須包含庫的頭文件,并且庫必須與程序鏈接在一起,可以使用編譯器標志來完成鏈接(例如,-lm,意為“鏈接數學庫”)。最常見的C庫是C標準庫,它由ISO和ANSI C標準指定,并隨每個C實現一起提供(針對嵌入式系統等有限環境的實現可能僅提供標準庫的子集)。C標準庫支持流輸入和輸出、內存分配、數學、字符字符串和時間值。標準頭文件(例如,stdio.h)為這些標準庫的接口規定提供了詳細的說明。
具體函數可根據需要查閱文檔并進行學習。這些函數可以幫助程序員更輕松地進行各種任務。最常用的包括輸入輸出、字符串處理、數學計算三種函數,下面簡單介紹一下用法。
輸入輸出函數
C語言提供了一系列輸入輸出函數,用于與用戶進行交互,從文件中讀取數據或將數據寫入文件。其中,最常用的輸入輸出函數是printf和scanf。
printf
printf函數用于格式化輸出到標準輸出設備(通常是屏幕)。它可以將文本和變量的值格式化后輸出。
scanf
scanf函數用于格式化輸入,從標準輸入設備(通常是鍵盤)讀取數據并存儲到變量中。
格式化輸出和輸入
可以使用格式控制符來指定輸出和輸入的格式。例如,`%d`表示整數,`%f`表示浮點數,`%s`表示字符串等。
字符串處理函數
C語言提供了一些字符串處理函數,用于操作和處理字符數組(字符串)。一些常用的字符串處理函數包括strcpy,strcat和strlen。
strcpy
strcpy函數可以用于將一個字符串復制到另一個字符串。
strcat
strcat函數可以用于將一個字符串連接到另一個字符串的末尾。
strlen
strlen函數用于計算字符串的長度(不包括空字符)。
數學函數
C語言提供了許多數學函數,位于數學庫<數學h>中,用于執行各種數學運算。以下是一些常用的數學函數:
sqrt
sqrt函數可以計算提供數的平方根。
sin和cos
預處理器和編譯過程
在C語言中,預處理器和編譯過程是代碼從源代碼到可執行文件的重要步驟。它們是在程序構建過程中的前兩個階段,負責預處理源代碼和將其翻譯為可執行的機器代碼。預處理器在源代碼級別進行文本處理和宏展開,編譯過程將中間代碼翻譯為匯編語言和機器碼,并最終生成可執行文件。這兩個階段在C語言編程中起著重要作用,有助于確保代碼的正確性和可執行性。
預處理
預處理(Preprocess)是C語言編譯過程的第一個階段,即對源代碼進行預處理,進行一些文本替換和宏展開,生成經過處理的中間代碼。預處理指令以 `#` 開頭,例如 “#include”用于包含頭文件、“#define”用于定義宏等。預處理器在生成中間代碼后,將其傳遞給編譯器進行編譯。
編譯
編譯(Compile)是C語言構建過程的第二個階段。在這個階段,編譯器將預處理器生成的中間代碼翻譯成匯編語言,然后再將匯編語言翻譯為機器碼,最終生成可執行文件。編譯過程包括以下主要步驟:
常用工具
常用的預處理器和編譯器有:
實際應用與案例
實際應用
系統編程
在系統編程中,C語言廣泛用于開發操作系統、設備驅動程序和系統工具。C語言的文件操作函數,如fopen、fclose、fread、fwrite等,可以實現文件的讀寫、創建和管理。fork、exec、wait等進程控制函數可以管理進程的創建、執行和等待。這些特點讓C語言被廣泛用于開發系統工具,如編譯器、解釋器、調試器等,幫助程序員更好地開發和維護代碼。比如Linux內核是由C語言編寫的,以及Windows操作系統中的進程管理功能和它的大部分內核,也是通過C語言編寫的。
嵌入式開發
嵌入式系統中的C語言應用非常常見,因為C語言具有高效、可移植性和直接硬件控制能力。它允許程序員直接控制硬件,從而實現低功耗的設計,延長嵌入式設備的電池壽命。可以用于編寫實時系統,確保嵌入式系統按照嚴格的時間要求執行任務。比如Arduino,它是一個廣泛用于嵌入式開發的平臺,其編程語言就是基于C/C++。開發者可以使用Arduino IDE編寫C/C++代碼,與各種傳感器和執行器進行交互,從而創建物聯網設備、機器人、家用自動化系統等。還有實時操作系統(RTOS)如FreeRTOS等,可以在嵌入式系統上運行,它們的內核也通常是使用C語言編寫的。
游戲開發
C語言在游戲開發領域仍然有一定的影響力,盡管現代游戲引擎往往使用更高級的語言。使用C語言和圖形庫,如OpenGL,可以實現游戲中的圖形渲染和繪制。它可以用于實現游戲中的物理引擎,模擬物體的運動、碰撞等行為。此外游戲的核心邏輯部分通常由C語言編寫,包括游戲規則、AI算法等。比如毀滅戰士,它是1993年的3D第一人稱射擊游戲,使用C語言編寫了其引擎、游戲邏輯和渲染代碼,為游戲開發鋪平了道路。Allegro也是一個用于游戲開發的C/C++圖形庫,它支持2D圖形、聲音、輸入等,許多獨立游戲和小型游戲項目使用Allegro庫來實現游戲功能。
Hello World示例代碼
“Hello,World”示例最早出現在《C程序設計語言》的第一版中,已經成為大多數編程教材中引入程序的范例。此外,當涉及到編程時,"Hello World"程序通常是一個入門級的示例程序,用于展示一個基本的程序結構和輸出功能。以下是C語言中的一個簡單的"Hello World"程序示例:
這個程序使用了C語言的標準輸入輸出庫
安全性和低級編程
在C語言中,安全性與低級編程是一項關鍵的考慮因素,因為C語言提供了較高的靈活性和底層控制,但同時也使得編程者需要更加小心謹慎,以確保代碼的安全性和穩定性。主要包括以下問題:
影響與發展
影響和地位
C語言在系統級編程領域具有重要地位。由于C語言的底層性質和對硬件的直接控制能力,它成為開發操作系統、設備驅動程序和嵌入式系統的首選語言。許多操作系統的內核和底層組件都是用C語言編寫的,包括unix和Linux。此外C語言在不同硬件平臺之間具有很好的可移植性,這使得開發者可以編寫一次代碼,然后在多個平臺上運行,從而大大簡化了跨平臺開發。C語言還因其高效的性能而受到贊譽,特別適合需要高性能的應用程序,如圖像處理、游戲引擎等。C語言的發展還推動了編譯器和開發工具鏈的進步。很多編程語言的編譯器和工具都是用C語言編寫的,這包括C++、Java等。C語言的語法和結構直接影響了許多后續語言的設計。
許多程序員在職業生涯的早期都會學習和使用C語言,因為它不僅教授了基本編程概念,還幫助開發者理解計算機底層的工作原理。所以它被廣泛用于編程教育,特別是在計算機科學和工程學的課程中。學習C語言可以幫助學生培養良好的編程思維、算法和數據結構的理解,以及問題解決能力。
總之,C語言以其高度的靈活性、可移植性和性能,對計算機科學和軟件開發領域產生了深遠的影響。它在系統編程、跨平臺開發、編譯器工具鏈、軟件教育等方面都占據著重要地位,并為后續編程語言的發展鋪平了道路。
衍生語言
C語言對許多后來的編程語言產生了影響,特別是C++、C#等。C++和C#都是在C語言基礎上發展而來,它們在一些方面有共同之處,同時也有顯著的差異。C++是C語言的擴展,引入了面向對象編程(OOP)的概念。它保留了C語言的底層特性,同時添加了類、繼承、多態等面向對象的功能。C++適用于需要高性能、底層控制和面向對象編程的應用,如游戲開發、系統編程等。而C#是微軟開發的一種現代編程語言,它也支持面向對象編程,并且更加注重開發效率和可移植性。C#通常用于開發Windows應用程序、Web應用程序和移動應用程序。它提供了豐富的庫和框架,使開發變得更加簡單和高效。
參考資料 >
GCC, the GNU Compiler Collection.GNU Project.2023-08-01
Clang: a C language family frontend for LLVM.LLVM.2023-08-01
C language documentation.Microsoft Learn.2023-08-01
Imperative programming: Overview of the oldest programming paradigm.Digital Guide.2023-08-01
Programming in C: A Tutorial.Lysator.2023-08-16
TIOBE Index.TIOBE.2023-08-01
ISO/IEC 9899:1999 specification.Open Standards.2023-08-07
PDP-7 Definition.Linfo.2023-08-16
The Digital Equipment Corporation PDP-7.Columbia Edu.2023-08-16
BCPL to B to C.Lysator.2023-08-04
Ken Thompson (sitting)-&-Dennis Ritchie at PDP-11.Internet Archive.2023-08-17
History of C.Cppreference.2023-08-04
ANSI C 與 K&R C.北京大學數學科學學院.2023-08-06
C99 & Numeric computing.Dr. Dobb's Journal.2023-08-06
ISO/IEC 9899:201x.ISO/IEC.2023-08-06
The Standard.ISO.2023-08-06
ISO/IEC 9899:201x (ISO C11) Committee Draft.Open Standards.2023-08-07
Revise spelling of keywords, proposal for C23.Open Standards.2023-08-07
The constexpr specifier for object definitions.Open Standards.2023-08-07
Make false and true first-class language features, proposal for C23.Open Standards.2023-08-07
Introduce the nullptr constant.Open Standards.2023-08-07
Not-so-magic - typeof for C.Open Standards.2023-08-07
WG14-N2601 : Annex X - IEC 60559 interchange and extended types.Open Standards.2023-08-07
WR14-N3042 : Introduce the nullptr constant.Open Standards.2023-08-07
C語言數據類型分類.C語言中文網.2023-08-10
Programming languages — C.Internet Archive.2023-08-16
64-Bit Programming Models: Why LP64?.What is UNIX?.2023-08-07
C and C++ Integer Limits.Microsoft learn.2023-08-07
Width of an Integer Type.GNU.2023-08-07
不完全類型.Oracle.2023-08-10
指針聲明.Microsoft learn.2023-08-10
C Control Flow Examples .Programiz.2023-08-10
C 數據類型.菜鳥教程.2023-08-10
Microsoft Visual C++ Redistributable latest supported downloads.Microsoft Learn.2023-08-16
Cmake.Cmake.2023-08-16
程序設計語言.The Linux Kernel Archives.2023-08-07
Walkthrough: Creating Windows Desktop Applications (C++).Microsoft Learn.2023-08-10
Arduino Uno Rev3.Arduino Store.2023-08-17
走進 C 語言.徐越的編程書.2023-08-10
Allegro5.Github.2023-08-10
Doom.Steam.2023-08-17
什么是緩沖區溢出?.Cloudflare.2023-08-17
C# 語言介紹.Microsoft Learn.2023-08-10