c語言

一門面向過程、抽象化的通用程序設計語言

C語言是一門面向過程、抽象化的通用程序設計語言,廣泛應用於底層開發。C語言能以簡易的方式編譯、處理低級存儲器。C語言是僅產生少量的機器語言以及不需要任何運行環境支持便能運行的高效率程序設計語言。儘管C語言提供了許多低級處理的功能,但仍然保持著跨平台的特性,以一個標準規格寫出的C語言程序可在包括一些類似嵌入式處理器以及超級計算機等作業平台的許多計算機平台上進行編譯。

現在最新的C語言標準是C18。

基本簡介


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#等。
馮·諾依曼在1945年提出了現代計算機的若干思想,被後人稱為馮·諾依曼思想,這是計算機發展史上的里程碑。自1945年至今大多採用其結構,因此馮。諾依曼被稱為計算機之父,他的馮諾依曼體系結構計算機由運算器、控制器、存儲器、輸入設備、輸出設備五大部件構成。C語言擁有一套完整的理論體系經過了漫長的發展歷史,在編程語言中具有舉足輕重的地位。

發展歷史


C語言之所以命名為C,是因為 C語言源自Ken Thompson發明的B語言,而 B語言則源自BCPL語言。
1967年,劍橋大學的Martin Richards對CPL語言進行了簡化,於是產生了BCPL(Basic Combined Programming Language)語言。
c語言
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操作系統。
1971年,同樣酷愛Space Travel的Dennis M.Ritchie為了能早點兒玩上遊戲,加入了Thompson的開發項目,合作開發UNIX。他的主要工作是改造B語言,使其更成熟。
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源代碼編譯、連接成目標二進位文件之後即可運行。
1977年,丹尼斯·里奇發表了不依賴於具體機器系統的C語言編譯文本《可移植的C語言編譯程序》。
C語言繼續發展,在1982年,很多有識之士和美國國家標準協會(ANSI)為了使C語言健康地發展下去,決定成立C標準委員會,建立C語言的標準。委員會由硬體廠商、編譯器及其他軟體工具生產商、軟體設計師、顧問、學術界人士、C語言作者和應用程序員組成。1989年,ANSI發布了第一個完整的C語言標準——ANSI X3.159-1989,簡稱“C89”,不過人們也習慣稱其為“ANSI C”。C89在1990年被國際標準化組織(International Standard Organization,ISO)一字不改地採納,ISO官方給予的名稱為:ISO/IEC 9899,所以ISO/IEC9899:1990也通常被簡稱為“C90”。1999年,在做了一些必要的修正和完善後,ISO發布了新的C語言標準,命名為ISO/IEC 9899:1999,簡稱“C99”。
在2011年12月8日,ISO又正式發布了新的標準,稱為ISO/IEC9899:2011,簡稱為“C11”。

編程開發


編譯器

GCC,GNU組織開發的開源免費的編譯器
MinGW,Windows操作系統下的GCC
Clang,開源的BSD協議的基於LLVM的編譯器
Visual C++ :: cl.exe,Microsoft VC++自帶的編譯器

集成開發環境

Code::Blocks,開源免費的C/C++ IDE
CodeLite,開源、跨平台的C/C++集成開發環境
Dev-C++,可移植的C/C++IDE
C-Free
Light Table
Visual Studio系列

第一個程序


c語言
c語言
下面是一個在標準輸出設備 (stdout) 上,印出 "Hello, world!" 字元串的簡單程序。類似的程序,通常作為初學編程語言時的第一個程序:
#include int main(void){ printf("Hello, World! \n"); return 0;}

事例

● ● 程序的第一行#include 是預處理器指令,告訴 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主要介紹了以下特色:
結構體(struct)類型
長整數(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支持 long long, long double _Complex, float _Complex 等類型
● 支持不定長的數組,即數組長度可以在運行時決定,比如利用變數作為數組長度。聲明時使用 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 進位的浮點數的描述。
● printf scanf 的格式化串增加了對 long long int 類型的支持。
浮點數的內部數據描述支持了新標準,可以使用 #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 的 ,定義一些標準長度的 int 的 ,定義複數的 ,定義寬字元的 ,類似於泛型的數學函數 ,浮點數相關的 。在 增加了 va_copy 用於複製 ... 的參數。里增加了 struct tmx ,對 struct tm 做了擴展。
● 在C89隻允許使用形式的註釋,而C++則允許使用//形式的註釋,因此//形式的註釋被稱為C++風格。但許多C編譯系統再C99之前就已經支持這種方便的註釋方法,C99正式將//形式的註釋納入C語言的標準。
● 輸入輸出對寬字元以及長整數等做了相應的支持。GCC和其它一些商業編譯器基本都支持C99的大部分特性。

C11標準

● 2011年12月8日,國際標準化組織(ISO)和國際電工委員會(IEC)再次發布了C語言的新標準,名叫ISO/IEC 9899:2011 - Information technology -- Programming languages -- C ,簡稱C11標準,原名C1X。這是C語言的第三個官方標準,也是C語言的最新標準。
● 新的標準提高了對C++的兼容性,並增加了一些新的特性。這些新特性包括:
● ● 對齊處理(Alignment)的標準化(包括_Alignas標誌符,alignof運算符, aligned_alloc函數以及頭文件。
● ● _Noreturn 函數標記,類似於 gcc 的 __attribute__((noreturn))。
● ● _Generic 關鍵字。
● ● 多線程(Multithreading)支持,包括:_Thread_local存儲類型標識符,頭文件,裡面包含了線程的創建和管理函數。_Atomic類型修飾符和頭文件。
● ● 增強的Unicode的支持。基於C Unicode技術報告ISO/IEC TR 19769:2004,增強了對Unicode的支持。包括為UTF-16/UTF-32編碼增加了char16_t和char32_t數據類型,提供了包含unicode字元串轉換函數的頭文件.
● ● 刪除了 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語言
c語言
1、高級語言:它是把高級語言的基本結構和語句與低級語言的實用性結合起來的工作單元。
● 2、結構式語言:結構式語言的顯著特點是代碼及數據的分隔化,即程序的各個部分除了必要的信息交流外彼此獨立。這種結構化方式可使程序層次清晰,便於使用、維護以及調試。C 語言是以函數形式提供給用戶的,這些函數可方便的調用,並具有多種循環、條件語句控制程序流向,從而使程序完全結構化。
● 3、代碼級別的跨平台:由於標準的存在,使得幾乎同樣的C代碼可用於多種操作系統,如Windows、DOS、UNIX等等;也適用於多種機型。C語言對編寫需要進行硬體操作的場合,優於其它高級語言。
● 4、使用指針:可以直接進行靠近硬體的操作,但是C的指針操作不做保護,也給它帶來了很多不安全的因素。C++在這方面做了改進,在保留了指針操作的同時又增強了安全性,受到了一些用戶的支持,但是,由於這些改進增加語言的複雜度,也為另一部分所詬病。Java則吸取了C++的教訓,取消了指針操作,也取消了C++改進中一些備受爭議的地方,在安全性和適合性方面均取得良好的效果,但其本身解釋在虛擬機中運行,運行效率低於C++/C。一般而言,C,C++,java被視為同一系的語言,它們長期佔據著程序使用榜的前三名。

特有特點

● C語言是一個有結構化程序設計、具有變數作用域(variable scope)以及遞歸功能的過程式語言。
● C語言傳遞參數均是以值傳遞(pass by value),另外也可以傳遞指針(a pointer passed by value)。
● 不同的變數類型可以用結構體(struct)組合在一起。
● 只有32個保留字(reserved keywords),使變數、函數命名有更多彈性。
● 部份的變數類型可以轉換,例如整型和字元型變數。
● 通過指針(pointer),C語言可以容易的對存儲器進行低級控制。
● 預編譯處理(preprocessor)讓C語言的編譯更具有彈性。

優缺點

● 優點
● 1、簡潔緊湊、靈活方便
● C語言一共只有32個關鍵字,9種控制語句,程序書寫形式自由,區分大小寫。把高級語言的基本結構和語句與低級語言的實用性結合起來。C 語言可以像彙編語言一樣對位、位元組和地址進行操作,而這三者是計算機最基本的工作單元。
c語言
c語言
● 2、運算符豐富
● C語言的運算符包含的範圍很廣泛,共有34種運算符。C語言把括弧、賦值、強制類型轉換等都作為運算符處理。從而使C語言的運算類型極其豐富,表達式類型多樣化。靈活使用各種運算符可以實現在其它高級語言中難以實現的運算。
● 3、數據類型豐富
● C語言的數據類型有:整型、實型、字元型、數組類型、指針類型、結構體類型、共用體類型等。能用來實現各種複雜的數據結構的運算。並引入了指針概念,使程序效率更高。
● 4、表達方式靈活實用
● C語言提供多種運算符和表達式值的方法,對問題的表達可通過多種途徑獲得,其程序設計更主動、靈活。它語法限制不太嚴格,程序設計自由度大,如對整型量與字元型數據及邏輯型數據可以通用等。
● 5、允許直接訪問物理地址,對硬體進行操作
● 由於C語言允許直接訪問物理地址,可以直接對硬體進行操作,因此它既具有高級語言的功能,又具有低級語言的許多功能,能夠像彙編語言一樣對位(bit)、位元組和地址進行操作,而這三者是計算機最基本的工作單元,可用來寫系統軟體。
● 6、生成目標代碼質量高,程序執行效率高
● C語言描述問題比彙編語言迅速,工作量小、可讀性好,易於調試、修改和移植,而代碼質量與彙編語言相當。C語言一般只比彙編程序生成的目標代碼效率低10%~20%。
● 7、可移植性好
● C語言在不同機器上的C編譯程序,86%的代碼是公共的,所以C語言的編譯程序便於移植。在一個環境上用C語言編寫的程序,不改動或稍加改動,就可移植到另一個完全不同的環境中運行。
● 8、表達力強
● C語言有豐富的數據結構和運算符。包含了各種數據結構,如整型、數組類型、指針類型和聯合類型等,用來實現各種數據結構的運算。C語言的運算符有34種,範圍很寬,靈活使用各種運算符可以實現難度極大的運算。
● C語言能直接訪問硬體的物理地址,能進行位(bit)操作。兼有高級語言和低級語言的許多優點。
● 它既可用來編寫系統軟體,又可用來開發應用軟體,已成為一種通用程序設計語言。
● 另外C語言具有強大的圖形功能,支持多種顯示器和驅動器。且計算功能、邏輯判斷功能強大。
● 缺點
● 1、 C語言的缺點主要表現在數據的封裝性上,這一點使得C在數據的安全性上有很大缺陷,這也是C和C++的一大區別。
● 2、 C語言的語法限制不太嚴格,對變數的類型約束不嚴格,影響程序的安全性,對數組下標越界不作檢查等。從應用的角度,C語言比其他高級語言較難掌握。也就是說,對用C語言的人,要求對程序設計更熟練一些。

C11新特性

● 1、對齊處理(Alignment)的標準化(包括_Alignas標誌符,alignof運算符,aligned_alloc函數以及頭文件)。
● 2、_Noreturn 函數標記,類似於 gcc 的 __attribute__(noreturn)。
● 3、_Generic關鍵字。
● 4、多線程(Multithreading)支持,包括:_Thread_local存儲類型標識符,;頭文件,裡面包含了線程的創建和管理函數。
● 5、刪除了 gets()函數,使用一個新的更安全的函數gets_s()替代。
● 6、增加了邊界檢查函數介面,定義了新的安全的函數,例如 fopen_s(),strcat_s()等等。
● 7、增加了更多浮點處理宏。
● 8、匿名結構體/聯合體支持,這個在gcc早已存在,C11將其引入標準。
● 9、靜態斷言(Static assertions),_Static_assert(),在解釋 #if 和 #error 之後被處理。
● 10、新的 fopen()模式,(“…x”),類似 POSIX 中的 O_CREAT|O_EXCL,在文件鎖中比較常用。
● 11、新增 quick_exit()函數作為第三種終止程序的方式。當 exit()失敗時可以做最少的清理工作。
● 12、_Atomic類型修飾符和頭文件。

語言組成


基本構成

● 數據類型
● C的數據類型包括:整型、字元型、實型或浮點型(單精度和雙精度)、枚舉類型、數組類型、結構體類型、共用體類型、指針類型和空類型。
● 常量與變數
● 常量其值不可改變,符號常量名通常用大寫。
● 變數是以某標識符為名字,其值可以改變的量。標識符是以字母或下劃線開頭的一串由字母、數字或下劃線構成的序列,請注意第一個字元必須為字母或下劃線,否則為不合法的變數名。變數在編譯時為其分配相應存儲單元。
● 數組
● 如果一個變數名後面跟著一個有數字的中括弧,這個聲明就是數組聲明。字元串也是一種數組。它們以ASCII的NULL作為數組的結束。要特別注意的是,方括內的索引值是從0算起的。
● 指針
● 如果一個變數聲明時在前面使用 * 號,表明這是個指針型變數。換句話說,該變數存儲一個地址,而 *(此處特指單目運算符 * ,下同。C語言中另有 雙目運算符 *)則是取內容操作符,意思是取這個內存地址里存儲的內容。指針是 C 語言區別於其他同時代高級語言的主要特徵之一。
● 指針不僅可以是變數的地址,還可以是數組、數組元素、函數的地址。通過指針作為形式參數可以在函數的調用過程得到一個以上的返回值,不同於return(z)這樣的僅能得到一個返回值。
● 指針是一把雙刃劍,許多操作可以通過指針自然的表達,但是不正確的或者過分的使用指針又會給程序帶來大量潛在的錯誤。
● 字元串
● C語言的字元串其實就是以'\0'字元結尾的char型數組,使用字元型並不需要引用庫,但是使用字元串就需要C標準庫裡面的一些用於對字元串進行操作的函數。它們不同於字元數組。使用這些函數需要引用頭文件
● 文件輸入/輸出
● 在C語言中,輸入和輸出是經由標準庫中的一組函數來實現的。在ANSI C中,這些函數被定義在頭文件;中。
● 標準輸入/輸出
● 有三個標準輸入/輸出是標準I/O庫預先定義的:
● stdin標準輸入
● stdout標準輸出
● stderr輸入輸出錯誤
● 運算
● C語言的運算非常靈活,功能十分豐富,運算種類遠多於其它程序設計語言。在表達式方面較其它程序語言更為簡潔,如自加、自減、逗號運算和三目運算使表達式更為簡單,但初學者往往會覺的這種表達式難讀,關鍵原因就是對運算符和運算順序理解不透不全。當多種不同運算組成一個運算表達式,即一個運算式中出現多種運算符時,運算的優先順序和結合規則顯得十分重要。在學習中,對此合理進行分類,找出它們與數學中所學到運算之間的不同點之後,記住這些運算也就不困難了,有些運算符在理解后更會牢記心中,將來用起來得心應手,而有些可暫時放棄不記,等用到時再記不遲。
● 先要明確運算符按優先順序不同分類,《C程序設計》運算符可分為15種優先順序,從高到低,優先順序為1 ~ 15,除第2.13級和第14級為從右至左結合外,其它都是從左至右結合,它決定同級運算符的運算順序。

關鍵字

● 關鍵字又稱為保留字,就是已被C語言本身使用,不能作其它用途使用的字。例如關鍵字不能用作變數名、函數名等標識符
● 由ISO標準定義的C語言關鍵字共32個:
● auto double int struct break else long switch
● case enum register typedef char extern return union
● const float short unsigned continue for signed void
● default goto sizeof volatile do if while static inline
● restrict _Bool _Complex _Imaginary _Generic
● 基本數據類型
● void:聲明函數無返回值或無參數,聲明無類型指針,顯示丟棄運算結果。(C89標準新增)
● char:字元型類型數據,屬於整型數據的一種。(K&R時期引入)
● int:整型數據,表示範圍通常為編譯器指定的內存位元組長。(K&R時期引入)
● float:單精度浮點型數據,屬於浮點數據的一種。(K&R時期引入)
● double:雙精度浮點型數據,屬於浮點數據的一種。(K&R時期引入)
● _Bool:布爾型(C99標準新增)
● _Complex:複數的基本類型(C99標準新增)
● _Imaginary:虛數,與複數基本類型相似,沒有實部的純虛數(C99標準新增)
● _Generic:提供重載的介面入口(C11標準新增)
● 類型修飾關鍵字
● short:修飾int,短整型數據,可省略被修飾的int。(K&R時期引入)
● long:修飾int,長整型數據,可省略被修飾的int。(K&R時期引入)
● long long:修飾int,超長整型數據,可省略被修飾的int。(C99標準新增)
● signed:修飾整型數據,有符號數據類型。(C89標準新增)
● unsigned:修飾整型數據,無符號數據類型。(K&R時期引入)
● restrict:用於限定和約束指針,並表明指針是訪問一個數據對象的唯一且初始的方式。(C99標準新增)
● 複雜類型關鍵字
● struct:結構體聲明。(K&R時期引入)
● union:聯合體聲明。(K&R時期引入)
● enum:枚舉聲明。(C89標準新增)
typedef:聲明類型別名。(K&R時期引入)
● sizeof:得到特定類型或特定類型變數的大小。(K&R時期引入)
● inline:內聯函數用於取代宏定義,會在任何調用它的地方展開。(C99標準新增)
● 存儲級別關鍵字
● auto:指定為自動變數,由編譯器自動分配及釋放。通常在棧上分配。與static相反。當變數未指定時默認為auto。(K&R時期引入)
● static:指定為靜態變數,分配在靜態變數區,修飾函數時,指定函數作用域為文件內部。(K&R時期引入)
● register:指定為寄存器變數,建議編譯器將變數存儲到寄存器中使用,也可以修飾函數形參,建議編譯器通過寄存器而不是堆棧傳遞參數。(K&R時期引入)
● extern:指定對應變數為外部變數,即標示變數或者函數的定義在別的文件中,提示編譯器遇到此變數和函數時在其他模塊中尋找其定義。(K&R時期引入)
● const:指定變數不可被當前線程改變(但有可能被系統或其他線程改變)。(C89標準新增)
● volatile:指定變數的值有可能會被系統或其他線程改變,強制編譯器每次從內存中取得該變數的值,阻止編譯器把該變數優化成寄存器變數。(C89標準新增)
流程式控制制關鍵字
● 跳轉結構
● return:用在函數體中,返回特定值(如果是void類型,則不返回函數值)。(K&R時期引入)
● continue:結束當前循環,開始下一輪循環。(K&R時期引入)
● break:跳出當前循環或switch結構。(K&R時期引入)
● goto:無條件跳轉語句。(K&R時期引入)
● 分支結構
● if:條件語句,後面不需要放分號。(K&R時期引入)
● else:條件語句否定分支(與if連用)。(K&R時期引入)
● switch:開關語句(多重分支語句)。(K&R時期引入)
● case:開關語句中的分支標記,與switch連用。(K&R時期引入)
● default:開關語句中的“其他”分支,可選。(K&R時期引入)
編譯
● #define 預編譯宏
● #if 表達式 #else if 表達式 #else #endif 條件編譯
● #ifdef 宏 #else #endif 條件編譯
● #ifndef 宏 #else #endif 條件編譯與條件編譯

語法結構

順序結構
● 順序結構的程序設計是最簡單的,只要按照解決問題的順序寫出相應的語句就行,它的執行順序是自上而下,依次執行。
● 例如:a = 3,b = 5,現交換a,b的值,這個問題就好像交換兩個杯子水,這當然要用到第三個杯子,假如第三個杯子是c,那麼正確的程序為:c = a; a = b; b = c;執行結果是a = 5,b = c = 3如果改變其順序,寫成:a = b; c = a; b =c;則執行結果就變成a = b = c = 5,不能達到預期的目的,初學者最容易犯這種錯誤。順序結構可以獨立使用構成一個簡單的完整程序,常見的輸入、計算,輸出三步曲的程序就是順序結構,例如計算圓的面積,其程序的語句順序就是輸入圓的半徑r,計算s = 3.14159*r*r,輸出圓的面積s。不過大多數情況下順序結構都是作為程序的一部分,與其它結構一起構成一個複雜的程序,例如分支結構中的複合語句、循環結構中的循環體等。
選擇結構
● 順序結構的程序雖然能解決計算、輸出等問題,但不能做判斷再選擇。對於要先做判斷再選擇的問題就要使用選擇結構。選擇結構的執行是依據一定的條件選擇執行路徑,而不是嚴格按照語句出現的物理順序。選擇結構的程序設計方法的關鍵在於構造合適的分支條件和分析程序流程,根據不同的程序流程選擇適當的選擇語句。選擇結構適合於帶有邏輯或關係比較等條件判斷的計算,設計這類程序時往往都要先繪製其程序流程圖,然後根據程序流程寫出源程序,這樣做把程序設計分析與語言分開,使得問題簡單化,易於理解。程序流程圖是根據解題分析所繪製的程序執行流程圖。
循環結構
● 循環結構可以減少源程序重複書寫的工作量,用來描述重複執行某段演演算法的問題,這是程序設計中最能發揮計算機特長的程序結構,C語言中提供四種循環,即goto循環、while循環、do while循環和for循環。四種循環可以用來處理同一問題,一般情況下它們可以互相代替換,但一般不提倡用goto循環,因為強制改變程序的順序經常會給程序的運行帶來不可預料的錯誤。
● 特別要注意在循環體內應包含趨於結束的語句(即循環變數值的改變),否則就可能成了一個死循環,這是初學者的一個常見錯誤。
● 三個循環的異同點:用while和do…while循環時,循環變數的初始化的操作應在循環體之前,而for循環一般在語句1中進行的;while循環和for循環都是先判斷表達式,后執行循環體,而do…while循環是先執行循環體后判斷表達式,也就是說do…while的循環體最少被執行一次,而while循環和for就可能一次都不執行。另外還要注意的是這三種循環都可以用break語句跳出循環,用continue語句結束本次循環,而goto語句與if構成的循環,是不能用break和 continue語句進行控制的。
● 順序結構、分支結構和循環結構並不彼此孤立的,在循環中可以有分支、順序結構,分支中也可以有循環、順序結構,其實不管哪種結構,均可廣義的把它們看成一個語句。在實際編程過程中常將這三種結構相互結合以實現各種演演算法,設計出相應程序,但是要編程的問題較大,編寫出的程序就往往很長、結構重複多,造成可讀性差,難以理解,解決這個問題的方法是將C程序設計成模塊化結構。
● 具體內容:
● for循環結構是c語言中最具有特色的循環語句,使用最為靈活方便,它的一般形式為:
● for(表達式1;表達式2;表達式3)循環體語句。(其中;不能省略)
● 表達式
● 表達式1為初值表達式,用於在循環開始前為循環變數賦初值。
● 表達式2是循環控制邏輯表達式,它控制循環執行的條件,決定循環的次數。
● 表達式3為循環控制變數修改表達式,它使for循環趨向結束。
● 循環體語句是在循環控制條件成立的情況下被反覆執行的語句。
● 但是在整個for循環過程中,表達式1隻計算一次,表達式2和表達式3則可能計算多次,也可能一次也不計算。循環體可能多次執行,也可能一次都不執行。
● 先執行表達式2,然後執行循環結構,最後表達式3,一直這樣循環下去。
● for循環語句是c語言種功能最為強大的語句,甚至在一定程度上可以代替其他的循環語句
● do
● do循環結構,do 1 while⑵;的執行順序是1->2->1...循環,2為循環條件。
● while
● while循環結構,while(1) 2; 的執行順序是1->2->1...循環,1為循環條件
● 以上循環語句,當循環條件表達式為真則繼續循環,為假則跳出循環。

程序結構

● C語言的模塊化程序結構用函數來實現,即將複雜的C程序分為若干模塊,每個模塊都編寫成一個C函數,然後通過主函數調用函數及函數調用函數來實現一大型問題的C程序編寫,因此常說:C程序=主函數+子函數。因此,對函數的定義、調用、值的返回等中要尤其注重理解和應用,並通過上機調試加以鞏固。
判斷語句(選擇結構):
● if 語句:“如果”語句;if—else 語句:“若…(則)…否則…”語句;switch 語句:“切換”語句;switch—case:“切換—情況”語句。
循環語句(循環結構):
● while 語句:“當…”語句;do—while 語句:“做…當…(時候)”語句;for 語句:條件語句(即“(做)…為了…”語句)。
跳轉語句(循環結構:是否循環):
● goto 語句:“轉舵”語句,也稱“跳轉”語句;break 語句:“中斷”(循環)語句,即結束整個循環;continue 語句:“繼續”語句(結束本次循環,繼續下一次循環);return 語句:“返回”語句。
● 需要說明的是:
● ● 1、一個C語言源程序可以由一個或多個源文件組成。
● ● 2、每個源文件可由一個或多個函數組成。
● ● 3、一個源程序不論由多少個文件組成,都有一個且只能有一個main函數,即主函數。是整個程序的入口。
● ● 4、源程序中可以有預處理命令(包括include 命令,ifdef、ifndef命令、define命令),預處理命令通常應放在源文件或源程序的最前面。
● ● 5、每一個說明,每一個語句都必須以分號結尾。但預處理命令,函數頭和花括弧“}”之後不能加分號。(結構體、聯合體、枚舉型的聲明的“}”后要加“ ;”。)
● ● 6、標識符,關鍵字之間必須至少加一個空格以示間隔。若已有明顯的間隔符,也可不再加空格來間隔。
● 書寫規則
● ● 1、一個說明或一個語句佔一行。
● ● 2、用{} 括起來的部分,通常表示了程序的某一層次結構。{}一般與該結構語句的第一個字母對齊,並單獨佔一行。
● ● 3、低一層次的語句或說明可比高一層次的語句或說明縮進若干格后書寫。以便看起來更加清晰,增加程序的可讀性。在編程時應力求遵循這些規則,以養成良好的編程風格。

函數

● C程序是由一組變數或是函數的外部對象組成的。函數是一個自我包含的完成一定相關功能的執行代碼段。我們可以把函數看成一個“黑盒子”,你只要將數據送進去就能得到結果,而函數內部究竟是如何工作的,外部程序是不知道的。外部程序所知道的僅限於輸入給函數什麼以及函數輸出什麼。函數提供了編製程序的手段,使之容易讀、寫、理解、排除錯誤、修改和維護。
● C程序中函數的數目實際上是不限的,如果說有什麼限制的話,那就是,一個C程序中必須至少有一個函數,而且其中必須有一個並且僅有一個以main為名,這個函數稱為主函數,整個程序從這個主函數開始執行。
● C 語言程序鼓勵和提倡人們把一個大問題劃分成一個個子問題,對應於解決一個子問題編製一個函數,因此,C 語言程序一般是由大量的小函數而不是由少量大函數構成的,即所謂“小函數構成大程序”。這樣的好處是讓各部分相互充分獨立,並且任務單一。因而這些充分獨立的小模塊也可以作為一種固定規格的小“構件”,用來構成新的大程序。
● C語言發展的那麼多年來,用C語言開發的系統和程序浩如煙海。在發展的同時也積累了很多能直接使用的庫函數。
● ANSI C提供了標準C語言庫函數。
● C語言初學者比較喜歡的Turbo C 2.0提供了400多個運行時函數,每個函數都完成特定的功能,用戶可隨意調用。這些函數總體分成輸入輸出函數、數學函數、字元串和內存函數、與BIOS和DOS有關的函數、字元屏幕和圖形功能函數、過程式控制制函數、目錄函數等。
● Windows系統所提供的Windows SDK中包含了數千個跟Windows應用程序開發相關的函數。
● 其他操作系統,如Linux,也同樣提供了大量的函數讓應用程序開發人員調用。
● 作為程序員應盡量熟悉目標平台庫函數其功能。這樣才能遊刃有餘地開發特定平台的應用程序。比如作為Windows應用程序的開發者,應盡量熟悉Windows SDK;作為Linux應用程序開發者,應盡量熟悉Linux系統調用和POSIX函數規範。

運算符號

● 比較特別的是,比特右移(>>)運算符可以是算術(左端補最高有效位)或是邏輯(左端補 0)位移。例如,將 11100011 右移 3 比特,算術右移后成為 11111100,邏輯右移則為 00011100。因算術比特右移較適於處理帶負號整數,所以幾乎所有的編譯器都是算術比特右移。
● 運算符的優先順序從高到低大致是:單目運算符、算術運算符、關係運算符、邏輯運算符、條件運算符、賦值運算符(=)和逗號運算符。
()、 []、 -> 、 .、!、 ++、 --圓括弧、方括弧、指針、成員、邏輯非、自加、自減
++ 、 -- 、 * 、 & 、 ~ 、!單目運算符
+、 - 、 sizeof、(cast)
* 、 / 、%算術運算符
+ 、 -算術運算符
<< 、 >>位運算符
< 、 <= 、 > 、 >=關係運算符
== 、!=關係運算符號
&位與
^位異或
|位或
&&邏輯與
||邏輯或
? 、:條件運算符
/= 、%= 、 &= 、 |= 、 ^=賦值運算符
= 、 += 、 -= 、 *= 、
,順序運算符

經典錯誤


void main()的用法並不是任何標準制定的。 C語言標準語法是int main,任何實現都必須支持int main(void) { }和int main(int argc, char* argv[]) { }。
類似於a+=a++;或者(i++)+(i++)+(i++)屬於未定義行為,並不是說c語言中還未定義這種行為,它早有定論,它的結果取決於編譯器實現,不要寫這樣的代碼!

示常式序


下面是一個在標準輸出設備(stdout)上,印出"Hello, world!"字元串的簡單程序。類似的程序,通常作為初學編程語言時的第一個程序:
1
2
3
4
5
#include 
int main(){
printf("Hello, World! \n");
return 0;
}
● ● 程序的第一行#include是預處理器指令,告訴C編譯器在實際編譯之前要包含stdio.h文件。
● ● 下一行int main()是主函數,程序從這裡開始執行。
● ● 下一行printf(...)是C中另一個可用的函數,會在屏幕上顯示消息"Hello, World!"。
● ● 下一行return 0;終止main()函數,並返回值0。 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include
int main{
void move(int *xa,int *xb);
int a,b;
printf("請輸入兩個數a,b:");
scanf("%d,%d",&a,&b);
move(&a,&b);
printf("a=%d,b=%d\n",a,b);
return 0;
}
void move(int *xa,int *xb){
int a;
a=*xa;
*xa=*xb;
*xb=a;
}
1.程序的第三行是對函數的聲明,聲明了一個有兩個指針參數的無返回值函數。由於函數的定義在調用函數處下,所以必須進行聲明。
2.第四行是變數的定義,定義了兩個整型變數。
3.第六行輸入兩個數,必須以1,0這樣中間有逗號的方式輸入。把兩個數放入變數a,b內。"&"是取地址運算符。
4.第七行調用move函數,將兩個變數的值轉換。
5.main函數后就是move函數的定義。
從這個例子可以看出,指針變數可以獲得更多的返回值,這樣是非常方便的。