[go: nahoru, domu]

删除的内容 添加的内容
无编辑摘要
标签已被回退
FrankYang0610留言 | 贡献
无编辑摘要
 
(未显示23个用户的44个中间版本)
第2行:
{{Multiple issues|
{{too many sections}}
{{verylong}}
{{Trivia|time=2020-06-18T02:37:08+00:00}}
}}
第22行 ⟶ 第21行:
|name = C語言
|logo = File:The C Programming Language logo.svg
|logo_size = 220px160px
|logo caption =《[[C程序设计语言 (书)|C程序设计语言]]》,第一部介绍C语言的书籍
|paradigm = 程序式[[指令式编程]]([[过程式编程|过程式]])、[[结构化编程]]
|year = {{start date and age|1972}}
|designer = [[丹尼斯·里奇]](Dennis Ritchie)
|developer = [[丹尼斯·里奇]](Dennis Ritchie)和[[肯·汤普逊]](Ken Thompson)
|latest_release_version = [https://www.iso.org/standard/74528.html ISO/IEC 9899:2018]([[#C18|C18]])
|latest_release_date = 2018年6月
| typing = [[类型系统|静态]], [[弱类型]], {{le|明示类型|Manifest typing|明示}}, {{le|名称类型系统|Nominal type system|名称}}
|implementations = [[Clang]]、[[GCC]]、[[Microsoft Visual C++|MSVC]]、[[Turbo C]]、[[Watcom c|Watcom C]]
|influenced_by = [[B語言|B]]([[BCPL]]、[[CPL (程式語言)|CPL]])、[[ALGOL 68]]<ref name="dottcl"/>、[[組合語言]]、[[PL/I]]、[[FORTRAN]]
第36行:
|wikibooks = C Programming
}}
'''C语言'''(英語:'''C Language''')是一种通用的、[[过程式编程]][[程式語言]],支持[[结构化编程]]、词法作用域和[[递归]],使用静态类型系统,并且广泛用于[[系统软件]]与[[应用软件]]的开发。
'''C'''是一種通用的[[程式語言]],廣泛用於[[系統軟件]]與[[應用軟件]]的開發。於1969年至1973年間,為了移植與開發[[UNIX]][[作業系統]],由[[丹尼斯·里奇]]與[[肯·湯普遜]],以[[B語言]]為基础,在[[貝爾實驗室]]設計、開發出來。
 
C语言于1969年至1973年間,為了移植與開發[[UNIX]][[作業系統]],由[[丹尼斯·里奇]]與[[肯·汤普逊]],以[[B语言]]为基础,在[[贝尔实验室]]設計、开发出來。二十世纪八十年代,C语言应用日渐广泛。為了避免各開發廠商用的C語言的語法產生差異,[[美國國家標準局]]為C語言訂定了一套完整的國際標準語法,稱為[[ANSI C]],作為C語言的標準。与此同时,[[国际标准化组织]]也接受该标准为国际标准。因此,ANSI C也同时被称为ISO C。二十世纪八十年代至今的有关程式開發工具,一般都支持符合[[ANSI C]]的語法。
C語言具有高效、靈活、功能豐富、表達力强和較高的[[移植 (軟體)|可移植性]]等特點,在[[程序設計|程式設計]]中備受關注,成為最近25年使用最為廣泛的編程語言<ref name="AutoTX-3">{{cite web
 
C语言具有高效、灵活、功能丰富、表达力强和較高的[[移植 (軟體)|可移植性]]等特点,在[[程序设计|程式設計]]中备受青睐,成为最近25年使用最为广泛的编程语言<ref name="AutoTX-3">{{cite web
|url = http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html
|title = TIOBE Programming Community Index
第44行 ⟶ 第46行:
|accessdate = 2012-11-03
|language = en
|trans_title = TIOBE程社
|archive-date = 2018-12-25
|archive-url = https://web.archive.org/web/20181225175216/https://www.tiobe.com/tiobe-index/index/
|dead-url = yes
}}</ref>。目前,C言[[編譯器]]普遍存在於各種不同的[[操作系统]]中,例如[[Microsoft Windows]]、[[Mac OS X|macOS]]、[[Linux]]、[[Unix]]等。C語言的設計影響了多後來的程式語言,例如[[C++]]、[[Objective-C]]、[[Java]]、[[C♯|C#]]等。现行的许多软件都是由C语言或者其影响和衍生的编程语言开发出来的
 
二十世纪八十年代,為了避免各開發廠商用的C語言的語法產生差異,由[[美國國家標準局]]為C語言訂定了一套完整的國際標準語法,稱為[[ANSI C]],作為C語言的標準。二十世纪八十年代至今的有關程式開發工具,一般都支持符合[[ANSI C]]的語法。
<!--== 設計 ==
C語言設計目標是提供一種能以簡易的方式編譯、處理低階記憶體、產生少量的[[機械碼]]以及不需要任何執行環境支援便能執行的程式語言。C語言也很適合搭配[[汇编语言|-{zh-hans:汇编语言; zh-hant:組合語言;}-]]來使用。儘管C語言提供許多低階處理的功能,但仍保持良好[[跨平台]]的特性,以一個標準規格寫出的C語言程式可在許多電腦平台上進行編譯,甚至包含一些嵌入式理器([[微控制器]]或MCU)以及[[超級電腦]]等作業平台。-->
 
== 概述 ==
与[[ALGOL]]一族的大多数过程式编程语言类似,C語言是一個有結構化程式設計、具有变量作用域(variable scope)以及遞迴功能的程序式語言。其采用的静态类型系统可以防止无意的程序设计操作。C语言中所有的可执行代码都被包含在[[子程序]](函数)裡。其傳遞參數均是以值傳遞(pass by value)<ref>{{ Cite book | author = Brian W. Kernighan and Dennis M. Ritchie | title = The C programming Language | publisher = Prentice-Hall | date = 1988 | ISBN = 0-13-110362-8 | language = en | quote = In C, all function arguments are passed ``by value.'' }}</ref>,另外也可以傳遞指针(a pointer passed by value)。C语言是自由形式语言,即其源代码的缩进并不影响程序的功能,而是使用[[分号]]作为[[陈述式|语句]]的结尾,[[花括号]]来表示[[代码块]]。
=== 特性 ===
* C語言是一個有結構化程式設計、具有變量作用域(variable scope)以及遞迴功能的程序式語言。
* C語言傳遞參數均是以值傳遞(pass by value)<ref>{{ Cite book | author = Brian W. Kernighan and Dennis M. Ritchie | title = The C programming Language | publisher = Prentice-Hall | date = 1988 | ISBN = 0-13-110362-8 | language = en | quote = In C, all function arguments are passed ``by value.'' }}</ref>,另外也可以傳遞指针(a pointer passed by value)。
* 不同的變數類型可以用結構體(struct)組合在一起。<ref> {{Cite book | author = Dennis M. Ritchie,Brian W. Kernighan | title = C程序設計語言 | location = 北京 | publisher = 机械工业出版社 | date = 2004年1月 | ISBN = 9787111128069 | accessdate = 2020-06-10 | language = 中文 }} </ref>
* 只有32個保留字(reserved keywords),使變量、函數命名有更多彈性。<ref> {{Cite book | author = Dennis M. Ritchie,Brian W. Kernighan | title = C程序設計語言 | location = 北京 | publisher = 機械工業出版社 | date = 2004年1月 | ISBN = 9787111128069 | accessdate = 2020-06-10 | language = 中文 }} </ref>
* 部份的變量類型可以轉換,例如整數型和字符型變量。<ref> {{Cite book | author = Dennis M. Ritchie,Brian W. Kernighan | title = C程序設計語言 | location = 北京 | publisher = 机械工业出版社 | date = 2004年1月 | ISBN = 9787111128069 | accessdate = 2020-06-10 | language = 中文 }} </ref>
* 透過[[指標 (電腦科學)|指標]](pointer),C語言可以容易的對記憶體進行低階控制。<ref> {{Cite book | author = Dennis M. Ritchie,Brian W. Kernighan | title = C程序设计语言 | location = 北京 | publisher = 机械工业出版社 | date = 2004年1月 | ISBN = 9787111128069 | accessdate = 2020-06-10 | language = 中文 }} </ref>
* 編譯預處理(preprocessor)讓C語言的編譯更具有彈性。<ref> {{Cite book | author = Dennis M. Ritchie,Brian W. Kernighan | title = C程序設計語言 | location = 北京 | publisher = 機械工業出版社 | date = 2004年1月 | ISBN = 9787111128069 | accessdate = 2020-06-10 | language = 中文 }} </ref>
 
由于C语言的语言规模较小,若干高层的机制需要使用定义的函数来提供。比如,C语言并没有直接处理复合对象(例如[[字符串]]、集合、列表、数组等)的操作,也没有对于[[存储器]]分配工具和内存回收工具的直接定义,同时也本身不具有输入和输出以及文件访问的方法。然而,用户定义的函数和C语言[[标准库]]中的函数为这些高层的机制提供了可能性。<ref name="k&r中文"/>
== 歷史 ==
{{main|C語言的歷史}}
 
20世纪70年代,肯·湯姆森為了使其設計的Unix系統更加高效,使用B語C语也具有以下變種(即C語言)重寫了Unix。在1978年,[[丹尼斯·里奇]]和[[布萊恩·柯林漢]]合作出版了《[[C程序設計語言特性:<ref (书)|C程序設計語言]]》第一版,事實上即為Kname="k&R C标准<refr中文"> {{Cite book | author = StephenDennis PrataM. Ritchie,Brian W. Kernighan | title = C程序设计语言 Primer| Plus(第5版)url = https://archive.org/details/cchengxushejiyuy0000kern | location = 北京 | publisher = 人民郵電机械工业出版社 | date = 2005200421 | pages = 3-4 | ISBN = 97871151302289787111128069 | accessdate = 2020-0706-1510 | language = 中文 }} </ref>。在這之後,制定標準的工作轉移到ISO和ANSI。目前最新的C語言標準是[[C18 (C語言標準)|C18]]。更多關於C語言的歷史信息可以在[[C語言的歷史]]找到。
 
* 基本数据类型包括字符、整型和浮点数等。另外也有派生的各种数据类型,如[[指针]]、[[数组]]、结构和联合。
== 語法 ==
* 部份的变量類型可以轉換,例如整數型和字符型变量。
=== Hello World 程序 ===
* 透過[[指標 (電腦科學)|指標]](pointer),C語言可以容易的對記憶體進行低階控制。
[[File:Hello World Brian Kernighan 1978.jpg|縮略圖|Brain Kernighan於1978年親筆書寫的“Hello World”程序]]
* 不同的變數類型可以用結構体(struct)組合在一起。
下面是一個在標準輸出設備(stdout)上打印出 "[[Hello World程序|Hello, world!]]" 字串的簡單程式。類似的程式,通常作為初學程式語言時的第一個程式:
* 具有基本的控制流:语句组、条件判断、多路选择、循环等。
* 函数可以返回各种数据类型的值,并且都可以递归调用。每次调用函数会重新创建变量。
* C语言只有32個保留字(reserved keywords),使变量、函數命名有更多彈性。
* 编译预处理(preprocessor)讓C語言的編譯更具有彈性。
 
== 歷史 ==
<syntaxhighlight lang="c" line="1o">
{{main|C语言的历史}}
 
20世纪70年代,肯·汤姆森为了使其设计的Unix系统更加高效,使用B语言的变种(即C语言)在DEC PDP-7计算机上重写了Unix。C语言中许多重要概念来源于[[BCPL]]语言,其对C语言的影响也间接地来源于[[B语言]]。在1978年,[[丹尼斯·里奇]]和[[布萊恩·柯林漢]]合作出版了《[[C程序设计语言 (书)|C程序设计语言]]》第一版,事实上即为K&R C标准<ref> {{Cite book | author = Stephen Prata | title = C Primer Plus(第5版) | url = https://archive.org/details/cprimerplusdiwub0005unse | location = 北京 | publisher = 人民邮电出版社 | date = 2005年2月 | pages = [https://archive.org/details/cprimerplusdiwub0005unse/page/3 3]-4 | ISBN = 9787115130228 | accessdate = 2020-07-15 | language = 中文 }} </ref>。1983年,为了制定一个独立于具体机器且无歧义的C语言标准,[[美国国家标准协会]]成立了一个委员会,并在1988年完成了该标准的制定,即ANSI C。此标准同时被[[国际标准化组织]]所采纳,也被称作ISO C。
#include <stdio.h>
 
其后,C语言至今经历了几次标准更新,诞生了[[C99]]、[[C11 (C语言标准)|C11]]和目前最新的标准[[C18 (C语言标准)|C18]]。C语言标准的下一次更新C2x目前正在起草中。
int main(void)
{
printf("Hello, world!\n");
return 0;
}
 
== 語法 ==
</syntaxhighlight>
 
{{Main|C语言语法}}
其中只有int,void,return为C语言的关键字,[[C预处理器|预处理器]]会将<code>#include <stdio.h></code>替换为stdio.h文件的内容。
 
{{expand section}}
main函数是C语言程序的[[入口点]]。
 
C語言的语法相对简洁而直接。C语言的[[形式文法]]由[[国际标准化组织]]所制定。<ref name="isowg">{{Cite web|title=ISO/IEC JTC1/SC22/WG14 - C|url=http://www.open-std.org/jtc1/sc22/wg14/|language=en|archive-url=https://web.archive.org/web/20180212100115/http://www.open-std.org/jtc1/sc22/wg14/|archive-date=2018-02-12|accessdate=2022-04-02}}</ref>簡單來說,C語言包括如下文法:
<code>"Hello, world!\n"</code>中的<code>\n</code>是一个[[转义字符]],形式为<code>\</code>加上一个字符。所起的作用在[[ASCII]]码中规定。
 
# 作为一种[[指令式编程]]语言,C语言使用语句执行操作。最常见的语句是[[表达式]]语句,由一个表达式后加一个分号组成,可以令系统调用函数和为变量赋值;
printf是声明于stdio.h的函数,关于printf的更多细节,参见[[printf]];
# 註釋: C语言支持单行注释(以<code>//</code>开头)和多行注释(以<code>/*</code>开始,以<code>*/</code>结束);
 
# 数据类型: 基本的数据类型包括整数(<code>int</code>)、浮点数(<code>float</code>和<code>double</code>)、字符(<code>char</code>)、枚舉<code>enum</code>等;
关于格式化字符串的更多信息,参见[[格式化字符串]]。
# 数组: 数组是一组相同类型的数据元素的集合。使用以下方法初始化一個五個元素的整數數組:<syntaxhighlight lang="c">
 
int numbers[5] = {1, 2, 3, 4, 5};
=== 进一步了解 ===
C语言由函数和变量组成,C的函数就像是[[Fortran]]中的子程序和函数<ref> {{Cite book | author = Dennis M. Ritchie,Brian W. Kernighan | title = C程序设计语言 | location = 北京 | publisher = 机械工业出版社 | date = 2004年1月 | ISBN = 9787111128069 | accessdate = 2020-06-10 | language = 中文 }} </ref><ref>{{Cite web |url =http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2310.pdf |accessdate =2020-06-10 |title =ISO/IEC 9899:2018 |archive-date =2020-07-22 |archive-url =https://web.archive.org/web/20200722132012/http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2310.pdf |dead-url =no }}</ref>。
 
在C语言中,程序从 [[主函式#C/C++|<code>main</code>]] 开始执行。<code>main</code> 函数通过调用和控制其他函数进行工作。例如上面的<code>printf</code>。程序员可以自己写函数,或从库中调用函数。在上面的<code>return 0;</code> 使得 <code>main</code> 返回一个值给调用程序的[[壳层]],表明程序是否成功运行。
 
一个C语言的函数由返回值、函数名、参数列表和函数体组成。函数体的语法和其它的復合的语句部分是一样的。
 
=== 复合语句 ===
C語言中的復合語句(或称[[語句块]])的格式为:
 
<syntaxhighlight lang="c">
{
語句;
語句;
/* ... */
}
</syntaxhighlight>
# 封裝結構:结构(<code>struct</code>)、联合(<code>union</code>);
<ref>{{Cite web |url =http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2310.pdf |accessdate =2020-06-10 |title =ISO/IEC 9899:2018 |archive-date =2020-07-22 |archive-url =https://web.archive.org/web/20200722132012/http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2310.pdf |dead-url =no }}</ref>
# 結構化編程和控制结构: C语言包括条件语句(<code>if</code>、<code>else</code>)、循环语句(<code>for</code>、<code>while</code>、<code>do-while</code>)等;
復合語句可以使得几个語句从文法上变成一个語句。
# 跳轉語句:C語言允許使用跳轉關鍵字<code>goto</code>、<code>break</code>和<code>continue</code>來實現程序塊之間的跳轉,這和匯編語言的<code>jmp</code>關鍵字有一定相似處;
 
# 函数: C语言中的函数是程序的基本模块,可以自定义函数并在程序中调用;
有时必须使用復合語句,否则会产生错误。例如,在运用循环語句的时候,如果循环体(即循环中执行部分)包含多个語句(以分号隔开),则必须使用花括号将他们合并成一个復合語句。如果不这么做,系统仅把第一个分号前的内容看做循环体。
# 靈活且靠近底層的內存控制機制:C程序員可以自由選擇分配何種內存,以及分配多大的內存,如如下代碼所示:<syntaxhighlight lang="c">
 
int *array = (int *)malloc(5 * sizeof(int)); // 分配一個包含五個整數的數組
需要注意的是,部分C编译器并不支持在任意位置使用復合語句。
free(array); // 釋放使用malloc分配的內存
 
=== 條件語句 ===
C語言有两種條件語句形式,分别是<tt>if</tt>和<tt>switch</tt>。
 
If 的格式如下:
 
<syntaxhighlight lang="c">
if (運算式) // 如果
語句;
// 有時還會有 else:
else // 否則
語句;
</syntaxhighlight>
 
== Hello World 程序 ==
運算式的值非零表示條件為真;如果條件為假,程式將跳過<tt>if</tt>处的語句,直接執行<tt>if</tt>後面的語句。但是如果<tt>if</tt>後面有<tt>else</tt>,則當條件為假時,程式跳到<tt>else</tt>處執行。<tt>if</tt>和<tt>else</tt>後面的語句可以是另個<tt>if</tt>語句,這種套疊式的結構,允許更複雜的邏輯控制流程得以實現。在一般情況下,<tt>else</tt>一定與最接近的<tt>if</tt>成對,因此常用括弧<tt>'''{}'''</tt>越過此限制。比較下面兩種情況:
{{main|Hello World}}
[[File:Hello World Brian Kernighan 1978.jpg|缩略图|Brian Kernighan于1978年亲笔书写的“Hello World”程序]]
 
{{Quote box|
<syntaxhighlight lang="c">
width=25%
if (邏輯表達)
|align=right
if (邏輯表達式)
|quote="对于所有语言的初学者来说,编写的第一个程序几乎都是相同的,即‘请打印出下列内容 hello, world’"
語句;
|source=– 《C程序设计语言》<ref name="k&r中文"/>}}
else
語句;
</syntaxhighlight>下面是if的另一種格式if……else if……else……<syntaxhighlight lang="c">
if (邏輯表達式)
語句;
else if (邏輯表達式) //在下面可以加入多个“else if()”語句
語句;
else
語句;
</syntaxhighlight><syntaxhighlight lang="c" line="1">
if (邏輯表達式甲) {
if (邏輯表達式乙)
語句;
}
else
語句;
</syntaxhighlight>
要注意這裡的縮進和換行只用於方便閱讀。編輯器併不會根據縮進層級猜測 if 和 else 的對應關係。
 
现在广泛被编程初学者使用的"hello, world"程序实例最初就是出现在《[[C程序设计语言]]》第一版中。下面是一個在標準輸出設備(stdout)上打印出 "[[Hello World程序|Hello, world!]]" 字串的簡單程式。類似的程式,通常作為初學程式語言時的第一個程式:
<tt>switch</tt>通常用於對幾種有明確值的條件進行控制。它要求的條件值通常是整數或字元。與<tt>switch</tt>搭配的條件轉移是<tt>case</tt>。使用<tt>case</tt>後面的標值,控制程式將跳到滿足條件的<tt>case</tt>處一直往下執行,直到語句結束或遇到<tt>break</tt>。通常可以使用<tt>default</tt>把其他例外的情況包含進去。如果<tt>switch</tt>語句中的條件不成立,控制程式將跳到<tt>default</tt>處執行;如果省略<tt>default</tt>子句,則直接執行下一語句。<tt>switch</tt>是可以嵌套的。
 
<syntaxhighlight lang="c" line="1o">
switch (值) {
case 甲:
case 乙:
語句段1; // 甲乙都會執行
// 更多語句…
break; // 跳轉到 switch 末尾處
case 丙:
語句段2;
break;
default: // 無論如何都會匹配
語句段3;
}
</syntaxhighlight>
簡單的條件判斷也可用?:
 
#include <stdio.h>
<syntaxhighlight lang="c">
運算式?值1:值2;
如:
a=b>c?b:c // 如果變數"b"的值大於變數"c" 把變數"b"的值賦予變數"a"
</syntaxhighlight>
 
int main(void) {
=== 循環語句 ===
printf("Hello, world!\n");
C語言有三種形式的循環語句<ref>{{Cite web |url =http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2310.pdf |accessdate =2020-06-10 |title =ISO/IEC 9899:2018 |archive-date =2020-07-22 |archive-url =https://web.archive.org/web/20200722132012/http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2310.pdf |dead-url =no }}</ref>:
return 0;
<syntaxhighlight lang="c">
do
語句
while(判斷式);
</syntaxhighlight>
和:
<syntaxhighlight lang="c">
while(判斷式)
語句;
</syntaxhighlight>
和:
<syntaxhighlight lang="c">
for(起始化;判斷式;運算式)
語句;
</syntaxhighlight>
 
在<tt>while</tt>和<tt>for</tt>中,語句將執行到表達式的值為零時结束。在<tt>do...while</tt>語句中,循環將至少被執行一次。這三種循環結構可以互相轉化:
<syntaxhighlight lang="c">
for(起始化;判斷式;運算式)
語句;
</syntaxhighlight>
 
如果'''語句'''中不使用continue語句的話,相當於
<syntaxhighlight lang="c">
起始化;
while (判斷式) {
語句;
運算式;
}
</syntaxhighlight>
 
當循環條件一直為真時,將產生[[無窮迴圈]]。
 
=== 跳轉語句 ===
跳轉語句包括四種:<tt>goto,continue,break和return</tt><ref>{{Cite web |url =http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2310.pdf |accessdate =2020-06-10 |title =ISO/IEC 9899:2018 |archive-date =2020-07-22 |archive-url =https://web.archive.org/web/20200722132012/http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2310.pdf |dead-url =no }}</ref>。
 
<syntaxhighlight lang="c">
goto 標記;
</syntaxhighlight>
 
其中只有int,void,return为C语言的关键字,[[C预处理器|预处理器]]会将<code>#include <stdio.h></code>替换为stdio.h文件的内容。
<tt>goto</tt>語句是無條件轉移語句,且標記必須在當前函數中定義,使用“標記:”的格式定義。程式將跳到標記處繼續執行。由於<tt>goto</tt>(特别是向回 goto 和长距离的 goto)容易產生閱讀上的困難,所以对新手應該儘量少用。[[GCC]] 编译器拓展支持对指针 <tt>goto</tt>和宏内 goto,一定程度上增强了 goto 的可读性。
 
main函数是C语言程序的[[入口点]]。
 
<code>"Hello, world!\n"</code>中的<code>\n</code>是一个[[转义字符]],形式为<code>\</code>加上一个字符。所起的作用在[[ASCII]]码中规定。
<tt>continue</tt>語句用在迴圈語句中,作用是結束當前一輪的迴圈,馬上開始下一輪迴圈。
 
printf是声明于stdio.h的函数,关于printf的更多细节,参见[[printf]];
<tt>break</tt>語句用在迴圈語句或<tt>switch</tt>中,作用是結束當前迴圈,跳到循環體外繼續執行。但是使用<tt>break</tt>只能跳出一層迴圈。在要跳出多重迴圈時,可以使用<tt>goto</tt>使得程式更為簡潔。
 
关于格式化字符串的更多信息,参见[[格式化字符串]]。
當一個函數執行結束後要返回一個值時,使用<tt>return</tt>。<tt>return</tt>可以跟一個運算式或變數。如果<tt>return</tt>後面沒有值,將執行不返回值。
 
=== 在C語言中的運算符號 ===
 
見[[C和C++運算符]]。
 
=== 數據類型 ===
見[[數據類型 (C語言)]]。
 
=== 數組 ===
如果一個變數名後面跟著一個有數字的中括弧,這個聲明就是[[陣列]]聲明。字串也是一種陣列,它們以ASCII的NUL作為陣列的結束。要特別注意的是,方括內的索引值是從'''0'''算起的。
 
例如:
<syntaxhighlight lang="c">
int myvector [100];/* 從myvector[0]至[99]共100個元素 */
char mystring [80];
// 聲明時初始化
float mymatrix [3] [2] = {2.0 , 10.0, 20.0, 123.0, 1.0, 1.0};
int notfull [3][3] = {{1},{1,2,3},{4,5}};
// 數組套數組
char lexicon [10000] [300];/* 共一萬個最大長度為300的字元陣列。*/
int a[3][4];</syntaxhighlight>
 
上面最後一個例子創建了一個陣列,但也可以把它看成是一個多維陣列。注意陣列的下標從0開始。這個陣列的結構如下:
{| class="wikitable" style='font-family: monospace'
|-
| a[0][0] || a[0][1]
| a[0][2] || a[0][3]
|-
| a[1][0] || a[1][1]
| a[1][2] || a[1][3]
|-
| a[2][0] || a[2][1]
| a[2][2] || a[2][3]
|}
例子中notfull創建了一個3*3的二維陣列,初始化時有些元素並未賦值。如下:
1 ? ?
1 2 3
4 5 ?
根據C標準的規定,在存在初始化列表時,如果初始化列表中未提供對所有元素的初始化,則剩余元素会被默認初始化,併使用與静態變量相同的初始化規則<ref>{{Cite web|url=https://www.iso.org/standard/57853.html|title=ISO/IEC 9899:2011|publisher=International Organization for Standardization|accessdate=2020-03-08|language=en|archiveurl=https://web.archive.org/web/20200328063511/https://www.iso.org/standard/57853.html|archivedate=2020-03-28|quote=§6.7.9 Initialization 21 If there are fewer initializers in a brace-enclosed list than there are elements or members of an aggregate, or fewer characters in a string literal used to initialize an array of known size than there are elements in the array, the remainder of the aggregate shall be initialized implicitly the same as objects that have static storage duration.|dead-url=no}}</ref>。
 
==== 指針 ====
如果一个變量聲明時在前面使用 * 號,表明這是個指針型變量<ref>{{Cite web |url =http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2310.pdf |accessdate =2020-06-10 |title =ISO/IEC 9899:2018 |archive-date =2020-07-22 |archive-url =https://web.archive.org/web/20200722132012/http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2310.pdf |dead-url =no }}</ref>。換句话說,該變量存儲個个地址,而 *(此處特指'''單目運算符 *''',下同。C語言中另有雙目運算符 * 表示乘) 則是取内容操作符,意思是取這個内存地址里存儲的内容。把這两點結合在一起,可將 <code>int *a;</code>看作是 “*a 解得的内容類型為 int”,對更複雜的聲明也如此{{NoteTag|C 的聲明使用這種“解方程”的形式,於是便出現了多種複雜的聲明。https://cdecl.org 是一個基於網頁的實用“翻譯工具”。}}。指針是 C 語言區别於其他同時代高級語言的主要特征之一。
 
指針不僅可以是變量的地址,還可以是數組、數組元素、函數的地址。通過指針作為形式参數可以在函數的調用過程得到一個以上的返回值(不同於<code>return z</code>這樣的僅能得到一個返回值。
 
指針是一把雙刃劍,許多操作可以通過指針自然的表達,但是不正確的或者過分的使用指針又會結程序带来大量潛在的錯誤。
 
例如:
<syntaxhighlight lang="c">
int *pi; // 指向整型數據的指針 pi
int * api[3];// 由指向整型數據的指針構成的數組,長度為 3
char ** argv;// 指向一個字符指針的指針
struct { int member; } stinst,
* pst = & stinst;
// pst是一個指向一個匿名結構體的指針
</syntaxhighlight>
儲存在指針中的地址所指向的數值在程序中可以由 * 讀取。例如,在第一個例子中, <tt>*pi</tt> 是一個整型數據。這叫做引用一個指針。
 
另一個運算符 <tt>&</tt>,叫做取地址運算符,它将返回一個變量、数组或函数的存储地址。因此,下面的例子:
<syntaxhighlight lang="c">
int i, *pi; /* int and pointer to int */
pi = &i;
</syntaxhighlight>
<tt>i</tt> 和 <tt>*pi</tt> 在程序中可以相互替換使用,直到 <tt>pi</tt> 被改變成指向另一個變量的地址。
 
當指針指向結構體时,可以使用運算符 -> 代替 *和. 的作用,如 <tt>(*p).m</tt> 与 <tt>p->m</tt> 等效。
 
==== 字符串 ====
C語言的'''字符串'''其實就是char型數組,所以使用字符串並不需要引用庫。然而C標準庫確實包含了用於對字符串進行操作的函數,使得它們看起來就像字符串而不是陣列。使用這些函數需要引用[[標頭檔]]<tt>[[string.h]]</tt>。
 
=== 文件輸入/輸出 ===
在C語言中,輸入和輸出是經由標準函式庫中的一組函數來實現的。在ANSI/ISO C中,這些函數被定義在標頭檔<tt>stdio.h</tt>中。
 
==== 標準輸入/輸出 ====
有三個標準輸入/輸出是标准I/O库預先定義的:
<tt>
* stdin ''標準輸入''
* stdout ''標準輸出''
* stderr ''輸入輸出錯誤''</tt>
 
下面的這個例子顯示了一個過濾程式(filter program)是怎樣構成的。
 
<syntaxhighlight lang="C">
#include <stdio.h>
 
int main(int argc, const char * argv[])
{
char c;
while ((c=getchar())!=EOF)
putchar(c);
perror("getchar() got EOF");
return -1;
}
</syntaxhighlight>
 
=== 函數 ===
C語言的基本結構單位是函數<ref>{{Cite web |url =http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2310.pdf |accessdate =2020-06-10 |title =ISO/IEC 9899:2018 |archive-date =2020-07-22 |archive-url =https://web.archive.org/web/20200722132012/http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2310.pdf |dead-url =no }}</ref>。系统首先調用 [[主函式#C/C++|main函數(主函數)]],通過函數的嵌套调用,再調用其他函數。函數可以是系統自带的函數,也可以是用户定義的函數。C語言中,不允許函數嵌套定義。
 
== 内存管理 ==
C语言的特色之一是:程序员必须亲自处理内存的分配细节。语言不负责内存边界检查,这是因为在运行时进行内存边界检查会造成[[性能问题]],与[[Unix哲学|UNIX哲学]]不符。此特性容易导致[[缓冲区溢出]]问题。然而,部分编译器(如英特尔编译器)会出于安全性的考量,提供方法以进行运行时内存边界检查<ref>{{cite web |title=check-pointers, Qcheck-pointers |url=https://software.intel.com/content/www/us/en/develop/documentation/cpp-compiler-developer-guide-and-reference/top/compiler-reference/compiler-options/compiler-option-details/data-options/check-pointers-qcheck-pointers.html |website=Intel |accessdate=2021-06-01 |language=en |archive-date=2021-02-15 |archive-url=https://web.archive.org/web/20210215091914/https://software.intel.com/content/www/us/en/develop/documentation/cpp-compiler-developer-guide-and-reference/top/compiler-reference/compiler-options/compiler-option-details/data-options/check-pointers-qcheck-pointers.html }}</ref>。
C語言的特色之一是:程序員必須親自處理内存的分配細節。
 
大多C實現实现使用(Stack)来保存函返回地址/棧幀栈帧基址、完成函的参數傳遞数传递和函局部量的存。然而,在部分特殊的平台上,使用棧並栈并不能得最大效率。此實現实现編譯编译定<ref name="C18">{{Cite web |url =http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2310.pdf |accessdate =2020-06-10 |title =ISO/IEC 9899:2018 |archive-date =2020-07-22 |archive-url =https://web.archive.org/web/20200722132012/http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2310.pdf |dead-url =no }}</ref>。
如果程序需要在行的程中動態动态分配存,可以利用[[堆]](Heap)來實現来实现
 
基本上C程序的元素存存的候有3分配策略:
 
* 靜態静态分配
如果一個變个变[[全局量]]或者是函的[[靜態變静态变量]],這個變这个变量的存儲將储将使用靜態静态分配方式。靜態静态分配的存一般編譯编译器放在[[數據数据段]]或[[代段]],具決於實現决于实现這樣这样做的前提是,在'''編譯時编译时'''就必須確须确量的大小。
以IA32的x86平台及gcc編譯编译例,全局及靜態變静态变量放在數據数据段的低端;全局及靜態静态常量放在代段的高端。
 
* 自分配
的自局部應該隨著应该随着的返回動釋动释放(失效),這個这个要求在一般的系中都是利用(Stack)來滿来满足的。相比於靜態于静态分配,這時这时候,就不必絕對绝对要求這個變这个变量在'''編譯時编译时'''就必須確须确量的大小,''''''才定也不,但是C89仍然要求在'''編譯時编译时'''就要定,而C99放這個这个限制。但無論无论是C89是C99,都不允分配的自動變动变大小。
 
所以'''C函應該应该返回一局部量的地址'''。
 
要指出的是,自分配也屬於動態属于动态分配,甚至可以用alloca函數來数来像分配堆(Heap)一樣進样进行分配,而且放是自的。
 
* 動態动态分配
有一更加特殊的情量的大小在有可能改,或者單個變单个变量大小不量的有很大性,不能靜態静态分配或者自分配,這時这时候可以使用[[] ](Heap)來滿来满足要求。 ANSI C定的堆操作函是malloc、calloc、realloc和free。
使用[[堆]](Heap)内存将带来额外的开销和风险。
 
使用堆(Heap)内存将带来额外的开销和风险。
== 安全问题 ==
C语言的特色之一是:语言不负责内存边界检查,这是因为在运行时进行内存边界检查会造成[[性能问题]],与UNIX哲学不符。此特性容易导致[[缓冲区溢出]]问题。然而,部分编译器{{Fact}}会出于安全性的考量,提供方法以进行运行时内存边界检查。
 
== 库 ==
第391行 ⟶ 第194行:
|<stdlib.h>||标准工具库函数
|-
|<string.h>||ASCIIZASCII字符串及任意内存处理函数
|-
|<nowiki><time.h></nowiki>||时间相关
|}
 
在94年的修正版中<tt>
 
<tt>
* <iso646.h>
* <wchar.h>
* <wctype.h></tt>
</tt>
 
在C99中增加了六個函式庫<tt>
 
<tt>
* <complex.h>
* <fenv.h>
第412行 ⟶ 第210行:
* <stdbool.h>
* <stdint.h>
* <tgmath.h></tt>
</tt>
 
以上是C语言的标准。各个系统各自又对C库函数进行的各种扩充,就浩如烟海了。如[[POSIX C]]、[[GNU C]]等。
第424行 ⟶ 第221行:
也有一些編譯器、程式庫或作業系統可以處理一些非標準C語言的功能,例如邊界值檢查、[[缓存溢出]]偵測、[[序列化]]及[[垃圾回收 (計算機科學)|自動垃圾回收]]功能。
 
使用像[[Valgrind]]或{{link-enle|IBM Rational Purify|Purify}}等軟體工具,或者連結有特別[[malloc]]函式的程式庫,有助於找出一些運行期記憶體使用的問題。
 
== 保留关键字 ==
以下是C语言的保留关键字:<ref>{{Cite web|url=https://www.iso.org/standard/57853.html|title=ISO/IEC 9899:2011|publisher=International Organization for Standardization|accessdate=2020-03-08|language=en|archiveurl=https://web.archive.org/web/20200328063511/https://www.iso.org/standard/57853.html|archivedate=2020-03-28|dead-url=no}}</ref>
 
{| class="wikitable" border="1" width="500" cellpadding="0" cellspacing="0"
|-----
| width="25%" | <tt>char</tt> || width="25%" | <tt>short</tt>
| width="25%" | <tt>int</tt> || width="25%" | <tt>unsigned</tt>
|-----
| width="25%" | <tt>long</tt> || width="25%" | <tt>float</tt>
| width="25%" | <tt>double</tt> || width="25%" | <tt>struct</tt>
|-----
| width="25%" | <tt>union</tt> || width="25%" | <tt>void</tt>
| width="25%" | <tt>enum</tt> || width="25%" | <tt>signed</tt>
|-----
| width="25%" | <tt>const</tt> || width="25%" | <tt>[[Volatile变量|volatile]]</tt>
| width="25%" | <tt>[[typedef]]</tt> || width="25%" | <tt>auto</tt>
|-----
| width="25%" | <tt>register</tt> || width="25%" | <tt>static</tt>
| width="25%" | <tt>extern</tt> || width="25%" | <tt>break</tt>
|-----
| width="25%" | <tt>case</tt> || width="25%" | <tt>continue</tt>
| width="25%" | <tt>default</tt> || width="25%" | <tt>do</tt>
|-----
| width="25%" | <tt>else</tt> || width="25%" | <tt>for</tt>
| width="25%" | <tt>goto</tt> || width="25%" | <tt>if</tt>
|-----
| width="25%" | <tt>return</tt> || width="25%" | <tt>switch</tt>
| width="25%" | <tt>while</tt> || width="25%" | <tt>sizeof</tt>
|}
<!-- sizeof不属于关键字,只属于运算符 -->
=== C99新增关键字 ===
{| class="wikitable" border="1" width="500" cellpadding="0" cellspacing="0"
|-----
| width="20%" | <tt>_Bool</tt> || width="20%" | <tt>_Complex </tt>
| width="20%" | <tt>_Imaginary</tt> || width="20%" | <tt>inline</tt>|| width="20%" | <tt>restrict</tt>
|}
=== C11新增关键字 ===
{| class="wikitable" border="1" width="500" cellpadding="0" cellspacing="0"
|-----
| width="20%" | <tt>_Alignas</tt> || width="20%" | <tt>_Alignof </tt>
| width="20%" | <tt>_Atomic</tt> || width="20%" | <tt>_Generic</tt>|| width="20%" | <tt>_Noreturn</tt>
|-----
| width="25%" | <tt>_Static_assert</tt>|| width="25%" | <tt>_Thread_local</tt>
|}
 
== 經典錯誤 ==
第488行 ⟶ 第240行:
==參考資料==
{{div ref|
* [[Brian Kernighan]], [[Dennis Ritchie]]: ''[[The C Programming Language程序设计语言 (book)|The C Programming Language]]''. Also known as 亦被称作K&R — The original book on R,第一部介绍C.语言的书籍。
** 1st第一版, Prentice Hall 1978; ISBN 978-0-13-110163-0. Pre-ANSI /ISO标准化之前的C.
** 2nd第二版, Prentice Hall 1988; ISBN 978-0-13-110362-7. ANSI/ISO C.
** 中译本第二版,机械工业出版社 2004; ISBN 978-7-11-112806-9。
* [http://www.open-std.org/JTC1/SC22/WG14/www/standards ISO/IEC 9899]. The official C:1999 standard, along with technical corrigenda and a rationale. As of 2005 the latest version is [http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf ISO/IEC 9899:TC2].
* [[Samuel P. Harbison]], [[Guy L. Steele]]: ''C: A Reference Manual''. This book is excellent as a definitive reference manual, and for those working on C [[compiler]]s. The book contains a [[Backus-Naur form|BNF]] grammar for C.
第504行 ⟶ 第257行:
* [http://code-reference.com/c Coding Programmer Page / C Library Reference and Examples<nowiki></nowiki>]{{Wayback|url=http://code-reference.com/c |date=20130121220502 }} (english)
* [http://gcc.gnu.org/ GCC 首页]{{Wayback|url=http://gcc.gnu.org/ |date=20120111104818 }}
* [http://www.gnu.org/software/libc/ GLIBC2 首页]{{WebCiteWayback|url=https://www.webcitation.org/6I3qrgbid?url=http://www.gnu.org/software/libc/ |date=20130712170209 |dateformat=iso20130719081219 }}
* [http://www.microsoft.com/taiwan/vstudio/express/ Visual Studio Express 首頁]{{Wayback|url=http://www.microsoft.com/taiwan/vstudio/express/ |date=20070812203722 }}
* [http://www.open-std.org/JTC1/SC22/WG14/www/standards ISO/IEC 9899]{{Wayback|url=http://www.open-std.org/JTC1/SC22/WG14/www/standards |date=20150523043258 }}。C99标准的官方网站。目前(2020年)可直接下载的标准文本是 [http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2479.pdf ISO/IEC 9899:202x]{{Wayback|url=http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2479.pdf |date=20200610113538 }}。