常量(Constant)是程序中最基本的元素,有字元(Character)常量、整數(Integer)常量、浮點數(Floating Point)常量和枚舉常量。枚舉常量將在第 3 節 “數據類型標誌”介紹。下面看一個例子:
printf("character: %c\ninteger: %d\nfloating point: %f\n", '}', 34, 3.14);
字元常量要用單引號括起來,例如上面的'}'
,注意單引號只能括一個字元而不能像雙引號那樣括一串字元,字元常量也可以是一個轉義序列,例如'\n'
,這時雖然單引號括了兩個字元,但實際上只表示一個字元。和字元串字面值中使用轉義序列有一點區別,如果在字元常量中要表示雙引號"和問號?,既可以使用轉義序列\"
和\?
,也可以直接用字元"和?,而要表示'和\則必須使用轉義序列。[2]
計算機中整數和小數的內部表示方式不同(將在第 14 章 計算機中數的表示詳細介紹),因而在C語言中是兩種不同的類型(Type),例如上例的34
和3.14
,小數在計算機術語中稱為浮點數。這個語句的輸出結果和Hello world不太一樣,字元串"character: %c\ninteger: %d\nfloating point: %f\n"
並不是按原樣打印輸出的,而是輸出成這樣:
character: } integer: 34 floating point: 3.14
printf
中的第一個字元串稱為格式化字元串(Format String),它規定了後面幾個常量以何種格式插入到這個字元串中,在格式化字元串中%號(Percent Sign)後面加上字母c、d、f分別表示字元型、整型和浮點型的轉換說明(Conversion Specification),轉換說明只在格式化字元串中占個位置,並不出現在最終的打印結果中,這種用法通常叫做占位符(Placeholder)。這也是一種字面意思與真實意思不同的情況,但是轉換說明和轉義序列又有區別:轉義序列是編譯時處理的,而轉換說明是在運行時調用printf
函數處理的。源檔案中的字元串字面值是"character: %c\ninteger: %d\nfloating point: %f\n"
,\n
占兩個字元,而編譯之後保存在執行檔中的字元串是character: %c換行integer: %d換行floating point: %f換行
,\n
已經被替換成一個換行符,而%c
不變,然後在運行時這個字元串被傳給printf
,printf
再把其中的%c
、%d
、%f
解釋成轉換說明。
有時候不同類型的數據很容易弄混,例如"5"
、'5'
、5
,如果你注意了它們的界定符就會很清楚,第一個是字元串字面值,第二個是字元,第三個是整數,看了本章後面幾節你就知道為什麼一定要嚴格區分它們之間的差別了。
[2] 讀者可能會奇怪,為什麼需要規定一個轉義序列\?
呢?因為C語言規定了一些三連符(Trigraph),在某些特殊的終端上缺少某些字元,需要用Trigraph輸入,例如用??=
表示#字元。Trigraph極不常用,介紹這個只是為了讓讀者理解C語言規定轉義序列的作用,即特殊字元轉普通字元,普通字元轉特殊字元,?也是一種特殊字元。極不常用的C語法在本書中通常不會介紹。