跳轉到內容

C 程式設計/語言參考

來自華夏公益教科書
前一頁: 程式碼庫 C 程式設計 下一頁: 編譯器

關鍵字表

[編輯 | 編輯原始碼]

ANSI (美國國家標準協會) C (C89)/ISO C (C90)

[編輯 | 編輯原始碼]

非常舊的編譯器可能無法識別一些或所有 C89 關鍵字 const, enum, signed, void, volatile,以及任何更高版本的關鍵字。

  • auto
  • break
  • case
  • char
  • const
  • continue
  • default
  • do
  • double
  • else
  • enum
  • extern
  • float
  • for
  • goto
  • if
  • int
  • long
  • register
  • return
  • short
  • signed
  • sizeof
  • static
  • struct
  • switch
  • typedef
  • union
  • unsigned
  • void
  • volatile
  • while

ISO C (C99)

[編輯 | 編輯原始碼]

這些在大多數新的編譯器中都受支援。

  • _Bool
  • _Complex
  • _Imaginary
  • inline

ISO C (C11)

[編輯 | 編輯原始碼]

這些僅在一些較新的編譯器中受支援。

  • alignof
  • _Alignas
  • _Atomic
  • _Generic
  • _Noreturn
  • _Static_assert
  • _Thread_local

雖然從技術上講不是關鍵字,但支援 C99 的預處理器/編譯器還識別特殊預處理器運算子 _Pragma,它充當 #pragma 指令的替代形式,可以從宏展開中使用。例如,以下程式碼將導致一些編譯器(包括 GCC、Clang)發出診斷訊息。

    #define EMIT_MESSAGE(str)    EMIT_PRAGMA(message(str))
    #define EMIT_PRAGMA(content) _Pragma(#content)
    EMIT_MESSAGE("Hello, world!")

一些編譯器使用略微不同的語法;特別是,MSVC 支援 __pragma 而不是 _Pragma

特定編譯器也可以(在非標準相容模式下,或使用額外的語法標記,如 __extension__)將其他一些詞視為關鍵字,包括 asm, cdecl, far, fortran, huge, interrupt, near, pascal, 或 typeof。但是,它們通常允許在標準相容模式下透過宣告覆蓋這些關鍵字(例如,透過定義一個名為 typeof 的變數),以避免與現有程式產生不相容性。為了確保編譯器可以維護對擴充套件功能的訪問,這些編譯器通常有一組以兩個下劃線 (__) 開頭的專用關鍵字。例如,GCC 對 asm, __asm__asm__ 的處理方式大致相同,但後兩者始終保證具有預期的含義,因為它們不能被覆蓋。

許多新引入的關鍵字(即那些以下劃線和大寫字母開頭的關鍵字,如 _Noreturn_Imaginary)在大多數情況下僅用於間接使用。相反,程式設計師應該更傾向於使用標準標頭檔案,如 <stdbool.h><stdalign.h>,這些標頭檔案通常使用預處理器來建立關鍵字的全小寫變體(例如,complexnoreturn)。這些標頭檔案的作用是使 C 和 C++ 程式碼以及針對不同編譯器或語言版本的程式碼能夠更乾淨地互操作。例如,透過包含 <stdbool.h>booltruefalse 標記可以在 C99 或 C++ 中以相同的方式使用,而無需在 C99 中顯式使用 _Bool 或在 C++ 中顯式使用 bool

另請參閱保留識別符號列表[1]

運算子表

[編輯 | 編輯原始碼]

此表中同一行的運算子具有相同的優先順序,而求值的順序由結合性決定(從左到右從右到左)。表中越靠前的運算子優先順序越高,表中越靠後的運算子優先順序越低。

運算子 描述 示例用法 結合性
字尾運算子 從左到右
() 函式呼叫運算子 swap (x, y)
[] 陣列索引運算子 arr [i]
. 成員訪問運算子
對於結構體/聯合型別
或對它的引用
obj.member
-> 成員訪問運算子
對於指向結構體/聯合型別
物件的指標
ptr->member

一元運算子 從右到左
! 邏輯非運算子 !eof_reached
~ 按位非運算子 ~mask
+ -[2] 一元加/減運算子 -num
++ -- 後置遞增/遞減運算子 num++
++ -- 前置遞增/遞減運算子 ++num
& 取地址運算子 &data
* 間接定址運算子 *ptr
sizeof sizeof 運算子 用於表示式 sizeof 123
sizeof() sizeof 運算子 用於型別 sizeof (int)
(型別) 型別轉換運算子 (float)i

乘法運算子 從左到右
* / % 乘法、除法和
模運算子
celsius_diff * 9.0 / 5.0

加法運算子 從左到右
+ - 加法和減法運算子 end - start + 1

按位移位運算子 從左到右
<< 左移運算子 bits << shift_len
>> 右移運算子 bits >> shift_len

關係不等式運算子 從左到右
< > <= >= 小於、大於、小於或
等於、大於或等於
運算子
i < num_elements

關係等式運算子 從左到右
== != 等於、不等於 choice != 'n'

按位與運算子 從左到右
& bits & clear_mask_complement

按位異或運算子 從左到右
^ bits ^ invert_mask

按位或運算子 從左到右
| bits | set_mask

邏輯與運算子 從左到右
&& arr != 0 && arr->len != 0

邏輯或運算子 從左到右
|| arr == 0 || arr->len == 0
條件運算子 從右到左
?: size != 0 ? size : 0

賦值運算子 從右到左
= 賦值運算子 i = 0
+= -= *= /=
%= &= |= ^=
<<= >>=
簡寫賦值運算子
(foo op= bar 代表
foo = foo op bar)
num /= 10

逗號運算子 從左到右
, i = 0, j = i + 1, k = 0

資料型別表

[編輯 | 編輯原始碼]
型別 大小(以位計) 註釋 備用名稱
ANSI C (C89)/ISO C (C90) 中的原始型別
char ≥ 8
  • sizeof 給出以 char 單位的大小。這些“C 位元組”不一定是 8 位位元組(儘管通常是);位數由 limits.h 標頭檔案中的 CHAR_BIT 宏給出。
  • 符號性是實現定義的。
  • 8 位或更小的任何編碼(例如 ASCII)都可以用於儲存字元。
  • 整數運算只能針對 0 ~ 127 範圍內的值以可移植方式執行。
  • 所有位都對 char 的值有貢獻,即沒有“空洞”或“填充”位。
signed char char 相同
  • 字元儲存方式與 char 型別相同。
  • 可以以可移植方式儲存 -127 ~ 127 範圍內的整數[3]
unsigned char char 相同
  • 字元儲存方式與 char 型別相同。
  • 可以以可移植方式儲存 0 ~ 255 範圍內的整數。
short ≥ 16, ≥ char 的大小
  • 可以以可移植方式儲存 -32767 ~ 32767 範圍內的整數[4]
  • 用於減少記憶體使用量(雖然與使用 int 相比,生成的執行檔案可能更大,而且可能更慢)。
short int, signed short, signed short int
unsigned short short 相同
  • 可以以可移植方式儲存 0 ~ 65535 範圍內的整數。
  • 用於減少記憶體使用量(雖然與使用 int 相比,生成的執行檔案可能更大,而且可能更慢)。
unsigned short int
int ≥ 16,≥ short 的大小
  • 代表處理器處理資料的“正常”大小(字長);這是通常使用的整數資料型別。
  • 可移植地儲存 -32767 ~ 32767 範圍內的整數[4]
signedsigned int
unsigned int int 相同
  • 可以以可移植方式儲存 0 ~ 65535 範圍內的整數。
unsigned
long ≥ 32,≥ int 的大小
  • 可移植地儲存 -2147483647 ~ 2147483647 範圍內的整數[5]
long intsigned longsigned long int
unsigned long long 相同
  • 可移植地儲存 0 ~ 4294967295 範圍內的整數。
unsigned long int
float char 的大小
  • 當使用值變化範圍不大時,用於減少記憶體使用量。
  • 所使用的浮點格式由實現定義,不一定必須是 IEEE 單精度格式。
  • 不能指定 unsigned
double float 的大小
  • 代表處理器處理資料的“正常”大小;這是通常使用的浮點資料型別。
  • 所使用的浮點格式由實現定義,不一定必須是 IEEE 雙精度格式。
  • 不能指定 unsigned
long double double 的大小
  • 不能指定 unsigned

新增到 ISO C(C99)的原始型別
long long ≥ 64,≥ long 的大小
  • 可移植地儲存 -9223372036854775807 ~ 9223372036854775807 範圍內的整數[6]
long long intsigned long longsigned long long int
unsigned long long long long 相同
  • 可移植地儲存 0 ~ 18446744073709551615 範圍內的整數。
unsigned long long int
intmax_t 平臺支援的最大寬度
uintmax_t intmax_t 相同
  • 可以儲存 0 ~ (1 << n)-1 範圍內的整數,其中 'n' 是 uintmax_t 的寬度。

使用者定義型別
struct ≥ 每個成員大小的總和
  • 被稱為聚合型別
union ≥ 最大成員的大小
  • 被稱為聚合型別
enum char 的大小
  • 列舉是與 int 不同的型別,儘管它們可以互相轉換。
typedef 與正在命名的型別相同
  • typedef 的語法類似於儲存類,如 staticregisterextern

派生型別[7]
型別*

(指標)
char 的大小
  • 0 始終表示空指標(一個不能放置任何資料的地址),無論什麼位序列表示空指標的值。
  • 指向不同型別的指標可能具有不同的表示形式,這意味著它們的大小也可能不同。因此,它們不能互相轉換。
  • 即使在保證所有資料指標大小相同的實現中,函式指標和資料指標通常也彼此不相容。
  • 對於接受可變數量引數的函式,傳遞的引數必須是適當的型別,因此即使 0 也必須在這樣的函式呼叫中轉換為適當的型別。
型別 [整數[8]]

(陣列)
整數 × 型別 的大小
  • 方括號 ([]) 位於宣告中的識別符號名稱之後。
  • 在同時初始化陣列的宣告(包括函式引數宣告)中,陣列的大小(整數)可以省略。
  • 型別 []型別* 不同。只有在某些情況下才能將其中一個轉換為另一個。
型別 (逗號分隔的型別/宣告列表)

(函式)
  • 沒有宣告任何儲存類的函式為 extern
  • 圓括號 (()) 位於宣告中的識別符號名稱之後,例如 2 個引數的函式指標:int (* fptr) (int arg1, int arg2)

字元集

[編輯 | 編輯原始碼]

用 C 編寫的程式可以讀取和寫入任何字元集,前提是包含/使用了支援它們的庫。

但是,C 程式的原始碼通常限於 ASCII 字元集。

在包含原始碼的檔案中,行的結尾有時取決於它建立所在的系統,而不是換行符,但編譯器將每行的結尾視為單個換行符。

幾乎所有編譯器都允許字串常量中使用 $@` 字元。許多編譯器也允許文字多位元組 Unicode 字元,但它們不可移植。

某些字元必須用反斜槓轉義才能在字串或字元常量中表示自身。這些是

  • \\ 文字反斜槓
  • \" 文字雙引號
  • \' 文字單引號
  • \n 換行
  • \t 水平製表符
  • \f 換頁
  • \v 垂直製表符

此外,一些編譯器允許以下字元

  • \r 回車
  • \a 警報(可聽見的鈴聲)
  • \b 退格

\xhh,其中 'h' 字元是十六進位制數字,用於表示任意位元組(包括 \x00,即零位元組)。

\uhhhh\Uhhhhhhhh,其中 'h' 字元是十六進位制數字,用於可移植地表示 Unicode 字元。

參考文獻

[編輯 | 編輯原始碼]
  1. http://publib.boulder.ibm.com/infocenter/comphelp/v7v91/topic/com.ibm.vacpp7a.doc/language/ref/clrc02reserved_identifiers.htm 保留識別符號列表
  2. 非常舊的編譯器可能無法識別一元 + 運算子。
  3. -128 可以儲存在二進位制補碼機器(即大多數現有的機器)中。非常舊的編譯器可能無法識別 signed 關鍵字
  4. a b -32768 可以儲存在二進位制補碼機器(即大多數現有的機器)中。非常舊的編譯器可能無法識別 signed 關鍵字
  5. -2147483648 可以儲存在二進位制補碼機器(即大多數現有的機器)中。非常舊的編譯器可能無法識別 signed 關鍵字
  6. -9223372036854775808 可以儲存在二進位制補碼機器(即大多數現有的機器)中
  7. 標準沒有對整數的大小/型別有任何限制,它是由實現定義的。標準中唯一提到的內容是,實現可能有記憶體塊最大大小的限制,因此整數的限制將為 size_of_max_block/sizeof(type)
  8. 標準沒有對整數的大小/型別有任何限制,它是由實現定義的。標準中唯一提到的內容是,實現可能有記憶體塊最大大小的限制,因此整數的限制將為 size_of_max_block/sizeof(type)
前一頁: 程式碼庫 C 程式設計 下一頁: 編譯器
華夏公益教科書