基本簡介 C語言是一門面向過程的計算機程式語言,與C++、Java等面向對象程式語言有所不同。C語言的設計目標是提供一種能以簡易的方式
編譯 、處理低級
存儲器 、僅產生少量的
機器碼 以及不需要任何運行環境支持便能運行的程式語言。C語言描述問題比彙編語言迅速,工作量小、可讀性好,易於
調試 、修改和移植,而
代碼質量 與
彙編語言 相當。C語言一般只比
彙編語言 代碼生成的
目標程式 效率低10%~20%。因此,C語言可以編寫系統軟體。
二十世紀八十年代,
美國國家標準局 為了避免各開發廠商用的C語言語法產生
差異 ,給C語言制定了一套完整的美國國家標準語法,稱為
ANSI C 。作為C語言最初的標準。2011年12月8日,
國際標準化組織 (ISO)和
國際電工委員會 (IEC)發布的
C11標準 是C語言的第三個官方標準,也是C語言的最新
標準 ,該標準更好的支持了漢字函式名和漢字標識符,一定程度上實現了漢字編程。
C語言編譯器普遍存在於各種不同的作業系統中,例如Microsoft Windows, Mac OS X, Linux, Unix等。C語言的設計影響了眾多後來的程式語言,例如C++、Objective-C、Java、C#等。
發展歷史 1967年,
劍橋大學 的Martin Richards對CPL語言進行了簡化,於是產生了BCPL(Basic Combined Programming Language)語言。
c語言宣傳圖 20世紀60年代,美國
AT&T 公司
貝爾實驗室 (AT&T Bell Laboratory)的研究員
Ken Thompson 閒來無事,手癢難耐,想玩一個他自己編的,模擬在太陽系航行的電子遊戲——Space Travel。他背著老闆,找到了台空閒的機器——
PDP-7 。但這台機器沒有作業系統,而遊戲必須使用作業系統的一些功能,於是他著手為PDP-7開發作業系統。後來,這個作業系統被命名為——
UNIX 。
1970年,美國貝爾實驗室的 Ken Thompson,以
BCPL 語言為基礎,設計出很簡單且很接近硬體的B語言(取BCPL的首字母)。並且他用B語言寫了第一個UNIX作業系統。
1972年,美國
貝爾實驗室 的 D.M.Ritchie 在B語言的基礎上最終設計出了一種新的
語言 ,他取了BCPL的第二個字母作為這種語言的名字,這就是C語言。
1973年初,C語言的主體完成。Thompson和Ritchie迫不及待地開始用它完全重寫了
UNIX 。此時,編程的樂趣使他們已經完全忘記了那個"Space Travel",一門心思地投入到了UNIX和C語言的開發中。隨著UNIX的發展,C語言自身也在不斷地完善。直到今天,各種版本的UNIX核心和周邊工具仍然使用C語言作為最主要的開發語言,其中還有不少繼承Thompson和Ritchie之手的代碼。
在開發中,他們還考慮把
UNIX 移植到其他類型的計算機上使用。C語言強大的移植性(Portability)在此顯現。機器語言和
彙編語言 都不具有移植性,為
x86 開發的程式,不可能在Alpha,
SPARC 和
ARM 等機器上運行。而C語言程式則可以使用在任意架構的
處理器 上,只要那種架構的處理器具有對應的C語言
編譯器 和庫,然後將C原始碼
編譯 、
連線 成目標
二進制檔案 之後即可運行。
C語言繼續發展,在1982年,很多有識之士和
美國國家標準協會 為了使這個語言健康地發展下去,決定成立C標準委員會,建立C語言的標準。委員會由硬體廠商,編譯器及其他軟體工具生產商,軟體設計師,顧問,學術界人士,C語言作者和應用程式員組成。1989年,
ANSI 發布了第一個完整的C語言標準——ANSI X3.159—1989,簡稱“C89”,不過人們也習慣稱其為“
ANSI C ”。C89在1990年被
國際標準組織 ISO(International Standard Organization)一字不改地採納,ISO官方給予的名稱為:ISO/IEC 9899,所以ISO/IEC9899: 1990也通常被簡稱為“C90”。1999年,在做了一些必要的修正和完善後,ISO發布了新的C語言標準,命名為ISO/IEC 9899:1999,簡稱“
C99 ”。在2011年12月8日,ISO又正式發布了新的
標準 ,稱為ISO/IEC9899: 2011,簡稱為“
C11 ”。
編程開發 編譯器 Clang ,開源的BSD協定的基於LLVM的編譯器
集成開發環境 Light Table
第一個程式 下面是一個在標準輸出設備 (stdout) 上,印出 "
Hello, world !" 字元串的簡單程式。類似的程式,通常作為初學程式語言時的第一個程式:
#include <stdio.h>int main(){printf("Hello, World! \n"); return 0;} 事例 程式的第一行#include <stdio.h> 是預處理器指令,告訴 C 編譯器在實際編譯之前要包含 stdio.h 檔案。
下一行int main() 是主函式,程式從這裡開始執行。
下一行printf(...) 是 C 中另一個可用的函式,會在螢幕上顯示訊息 "Hello, World!"。
下一行return 0; 終止 main() 函式,並返回值 0。
語言標準 起初,C語言沒有官方標準。1978年由
美國電話電報公司 (AT&T)貝爾實驗室正式發表了C語言。布萊恩·柯林漢(Brian Kernighan) 和 丹尼斯·里奇(Dennis Ritchie) 出版了一本書,名叫《
The C Programming Language 》。這本書被 C語言開發者們稱為
K&R ,很多年來被當作 C語言的非正式的標準說明。人們稱這個版本的 C語言為
K&R C 。
K&R C主要介紹了以下特色:
長整數(long int)類型
無符號整數(unsigned int)類型
把運算符=+和=-改為+=和-=。因為=+和=-會使得編譯器不知道使用者要處理i = -10還是i =- 10,使得處理上產生混淆。
即使在後來
ANSI C 標準被提出的許多年後,K&R C仍然是許多編譯器的最 準要求,許多老舊的編譯器仍然運行K&R C的標準。
1970到80年代,C語言被廣泛套用,從大型主機到小型微機,也衍生了C語言的很多不同版本。
1983年,美國國家標準協會(ANSI)成立了一個委員會X3J11,來制定 C語言標準。
1989年,美國
國家標準 協會(ANSI)通過了C語言標準,被稱為
ANSI X3.159-1989 "Programming Language C" 。因為這個標準是1989年通過的,所以一般簡稱
C89標準 。有些人也簡稱
ANSI C ,因為這個標準是美國國家標準協會(ANSI)發布的。
1990年,
國際標準化組織 (ISO)和
國際電工委員會 (IEC)把C89標準定為C語言的國際標準,命名為
ISO/IEC 9899:1990 - Programming languages -- C 。因為此標準是在1990年發布的,所以有些人把簡稱作
C90標準 。不過大多數人依然稱之為
C89標準 ,因為此標準與ANSI C89標準完全等同。
1994年,國際標準化組織(ISO)和國際電工委員會(IEC)發布了C89標準修訂版,名叫ISO/IEC 9899:1990/Cor 1:1994,有些人簡稱為C94標準 。
1995年,國際標準化組織(ISO)和國際電工委員會(IEC)再次發布了C89標準修訂版,名叫ISO/IEC 9899:1990/Amd 1:1995 - C Integrity,有些人簡稱為C95標準 。
C99標準 1999年1月,國際標準化組織(ISO)和國際電工委員會(IEC)發布了C語言的新標準,名叫ISO/IEC 9899:1999 - Programming languages -- C ,簡稱C99標準 。這是C語言的第二個官方標準。
在C99中包括的特性有:
增加了對編譯器的限制,比如源程式每行要求至少支持到 4095 位元組,變數名函式名的要求支持到 63 位元組(extern 要求支持到 31)。
增強了預處理功能。例如:
宏支持取可變參數 #define Macro(...) __VA_ARGS__
使用宏的時候,允許省略參數,被省略的參數會被擴展成空串。
支持 // 開頭的單行注釋(這個特性實際上在C89的很多編譯器上已經被支持了)
增加了新
關鍵字 restrict, inline, _Complex, _Imaginary, _Bool
支持不定長的數組,即數組長度可以在運行時決定,比如利用變數作為數組長度。聲明時使用 int a[var] 的形式。不過考慮到效率和實現,不定長數組不能用在全局,或 struct 與 union 里。
變數聲明不必放在語句塊的開頭,for 語句提倡寫成 for(int i=0;i<100;++i) 的形式,即i 只在 for 語句塊內部有效。
允許採用(type_name){xx,xx,xx} 類似於 C++ 的構造函式的形式構造匿名的結構體。
複合
字面量 :初始化結構的時候允許對特定的元素賦值,形式為:
struct test{int a[3],b;} foo[] = { [0].a = {1}, [1].a = 2 };
struct test{int a, b, c, d;} foo = { .a = 1, .c = 3, 4, .b = 5 }; // 3,4 是對 .c,.d 賦值的
格式化字元串中,利用 \u 支持 unicode 的字元。
支持 16 進制的浮點數的描述。
浮點數的內部數據描述支持了新標準,可以使用 #pragma 編譯器指令指定。
除了已有的 __line__ __file__ 以外,增加了 __func__ 得到當前的函式名。
允許編譯器化簡非常數的表達式。
修改了 /% 處理負數時的定義,這樣可以給出明確的結果,例如在C89中-22 / 7 = -3, -22% 7 = -1,也可以-22 / 7= -4, -22% 7 = 6。 而C99中明確為 -22 / 7 = -3, -22% 7 = -1,只有一種結果。
取消了函式返回類型默認為 int 的規定。
允許 struct 定義的最後一個數組不指定其
長度 ,寫做 [](flexible array member)。
const const int i 將被當作 const int i 處理。
增加和修改了一些標準頭檔案,比如定義 bool 的 <stdbool.h> ,定義一些標準長度的 int 的 <inttypes.h> ,定義複數的 <complex.h> ,定義寬字元的 <wctype.h> ,類似於泛型的數學函式 <tgmath.h>, 浮點數相關的 <fenv.h>。 在<stdarg.h> 增加了 va_copy 用於複製 ... 的參數。里增加了 struct tmx ,對 struct tm 做了擴展。
在C89隻允許使用/*...*/形式的注釋,而C++則允許使用//形式的注釋,因此//形式的注釋被稱為C++風格。但許多C編譯系統再C99之前就已經支持這種方便的注釋方法,C99正式將//形式的注釋納入C語言的標準。
輸入輸出對寬字元以及長整數等做了相應的支持。
C11標準 對齊 處理(Alignment)的標準化(包括_Alignas標誌符,alignof
運算符 , aligned_alloc函式以及<stdalign.h>
頭檔案 。
_Noreturn 函式標記,類似於 gcc 的 __attribute__((noreturn))。
_Generic 關鍵字。
多執行緒(Multithreading)支持,包括:
_Thread_local存儲類型標識符,<threads.h>頭檔案,裡面包含了執行緒的創建和管理函式。
_Atomic類型修飾符和<stdatomic.h>頭檔案。
增強的
Unicode 的支持。基於C Unicode技術報告ISO/IEC TR 19769:2004,增強了對Unicode的支持。包括為
UTF-16 /
UTF-32 編碼增加了char16_t和char32_t數據類型,提供了包含
unicode 字元串轉換函式的頭檔案<uchar.h>.
刪除了
gets () 函式,使用一個新的更安全的函式gets_s()替代。
增加了
邊界檢查 函式接口,定義了新的安全的函式,例如 fopen_s(),strcat_s() 等等。
增加了更多浮點處理宏。
匿名結構體/聯合體支持。這個在
gcc 早已存在,
C11 將其引入標準。
靜態斷言(static assertions),_Static_assert(),在解釋 #if 和 #error 之後被處理。
新的
fopen () 模式,(“…x”)。類似 POSIX 中的 O_CREAT|O_EXCL,在檔案鎖中比較常用。
新增 quick_exit() 函式作為第三種終止程式的方式。當
exit ()失敗時可以做最少的清理工作。
語言特點 基本特性 特有特點 C語言是一個有結構化程式設計、具有變數作用域(variable scope)以及遞歸功能的過程式語言。
C語言傳遞參數均是以值傳遞(pass by value),另外也可以傳遞指針(a pointer passed by value)。
不同的變數類型可以用
結構體 (struct)組合在一起。
只有32個保留字(reserved keywords),使變數、函式命名有更多彈性。
部份的變數類型可以轉換,例如整型和字元型變數。
通過指針(pointer),C語言可以容易的對存儲器進行低級控制。
預編譯 處理(preprocessor)讓C語言的編譯更具有彈性。
優缺點 C11新特性 語言組成 基本構成 關鍵字 流程控制關鍵字
編譯
語法結構 順序結構
選擇結構
循環結構
程式結構 判斷語句(選擇結構):
循環語句(循環結構):
跳轉語句(循環結構:是否循環):
書寫規則
函式 運算符號 ()、 []、 -> 、 .、!、 ++、 --
圓括弧、方括弧、指針、成員、邏輯非、自加、自減
++ 、 -- 、 * 、 & 、 ~ 、!
單目運算符
+、 - 、 sizeof、(cast)
* 、 / 、%
算術運算符
+ 、 -
算術運算符
<< 、 >>
位運算符
< 、 <= 、 > 、 >=
關係運算符
== 、!=
關係運算符號
&
位與
^
位異或
|
位或
&&
邏輯與
||
邏輯或
? 、:
條件運算符
/= 、%= 、 &= 、 |= 、 ^=
賦值運算符
= 、 += 、 -= 、 *= 、
,
順序運算符
經典錯誤 void main()的用法並不是任何標準制定的。 C語言標準語法是int main,任何實現都必須支持int main(void) { /* ... */ }和int main(int argc, char* argv[]) { /* ... */ }。
類似於a+=a++;或者(i++)+(i++)+(i++)屬於未定義行為,並不是說c語言中還未定義這種行為,它早有定論,它的結果取決於編譯器實現,不要寫這樣的代碼!