先看例子:
printf("This line has only controlling strings.\n");
`printf(“I am %d years old and %f inch tall”, 21, 132);
參數
printf()的參數分為兩大部分,分別是控制字符串和參數列表,二者用逗號隔開,而且參數之間也要用逗號隔開。其中控制字符串是字符串常量,如果不需要其他參數的話,雙引號裡面的文字將被原原本本的打印到屏幕。通俗的講,雙引號裡面是什麼,輸出的就是什麼,包括轉義字符。
但是,這樣以來,我們無論想要打印什麼,都只能手動的寫在雙引號內部,從而無法實現自動化打印。比如,怎樣輸出程序中變量的值?總不能變量的值變一次我們就手動改寫一次printf()函數吧?那就違背了寫程序的初衷。
所以必須要有一種辦法讓函數能打印變量的值,然而,把變量名稱直接寫進雙引號內部是不可行的,因為這時變量名就成了字符串常量的一部分——雙引號的內部的字符將被視為普通文本。
於是,在控制字符串中引入了一個特殊字符’%’,這個字符和後面的某些字符組合起來會轉義,即不會再被視為普通文本,而是有其他用途。比如上面例子中的%d,它表示這個位置要打印的是一個十進制數字而不是%d本身,實際的數值由字符串後面對應的變量或常量提供。%被稱為占位符,表示先占住一個固定的位置,然後再往裡面添加內容;d是格式說明符,表明以哪種格式打印對應的參數。%d合稱為格式占位符或轉換說明符。
可以看出,參數可以是變量也可以是常量,還可以是表達式。但是要注意的是,參數必須和控制字符串中轉換說明符的個數匹配且順序一致;還有,每個參數的類型要和對應的轉換說明符匹配,比如浮點數就不應該用%d打印。下面詳談各種轉換說明符的使用。
轉換說明符
上面所說的格式轉換到底是啥意思呢?我們要知道,任何數據在計算機中都是以二進制的形式存儲的,變量或常量對應的那塊存儲空間存放的可能是一串二進制數字:01000001,那麼把它理解為一個十六進制數字或者說以十六進制的形式打印出來就是0x41;以十進制的形式打印出來就是65;以ASCII字符的形式打印出來就是大寫字母’A’。* 所以,格式轉換的本質就是翻譯,把二進制數字翻譯成對應的形式。而各種格式說明符就是在指定翻譯的規則。*
下面我們逐個介紹這些格式說明符。
整數類型
%d 或 %i :有符號十進制整數,它們的效果是相同的,如下:
printf("this is %d and %i, same.\n", 10, 10);
輸出: this is 10 and 10, same.
%u : 無符號十進制整數:
printf("this is %d and %u.\n", -65, -65);
輸出:this is -65 and 4294967231.
我們看到,-65這個數以相同的二進制形式存儲,但解讀的時候發生了變異,原理見前文。
%x 或 %X: 十六進制無符號整數:
printf("this is %d and %x.\n", -65, -65);
printf("this is %d and %X.\n", -65, -65);
輸出: this is -65 and ffffffbf.
this is -65 and FFFFFFBF.
%o : 八進制無符號整數:
printf("this is %d and %o.\n", -65, -65);
浮點數類型
%f :十進制記數法的浮點數:printf("this is %f\n", 12.62543219);
%e 或 %E: e或E-記數法的浮點數:
printf("this is %e\n", 0.625);
printf("this is %e\n", 9000876.54);
輸出: this is 6.250000e-01
this is 9.000877e+06
可以看出%e或%E只能保留小數點後面六位數。
%g 或 %G :這時,printf把一個浮點數表示為e-記數法,且只保留六位有效數字;然後觀察指數,若指數在-4~+5之間時,自動選擇%f;反之選擇%e或%E(似乎還要復雜,大家自己判斷一下吧):
printf("this is %g and %g\n", 0.000089, 0.00089);
printf("this is %G and %G\n", 900876.44, 9000876.44);
輸出:this is 8.9e-05 and 0.00089
this is 900876 and 9.00088E+06
printf("this is %a and %A\n", 3.75, -3.75);
其他類型
%c :一個字符:printf("this is %c \n", 66);
printf("this is %s \n", "string");
printf("this is %p \n", "string");
printf("this is %% \n");
轉換說明修飾符
在%和格式說明符之間可以插入各種修飾符來進一步修改最終的打印結果,比如打印的寬度、精度、符號等等。
‘數字’:用來指定打印字段的最小寬度,若該寬度容納不下結果,則自動超過這個限制而使用更寬的字段:
printf("this is %6d \n", 65);
輸出:this is 65
‘.數字’:看配合對象,若是%f等浮點格式說明符,則指定浮點數的精度,即小數點右邊打印的數字的位數;對是%s,指定打印字符的最大數目;對整數格式,指定打印數字的最小位數(整數的精度?),不夠的話用0做前導填充;若小數點後面沒有數字,默認為0,即變成整數:
printf("this is /%.2f/\n", 65.3);
printf("this is /%.f/\n", 65.3);
printf("this is /%.3d/\n", 65);
輸出:this is /65.30/
this is /65/
this is /065/
‘-’:減號,用來指定對齊方式,從上面一條結果我們可以看出,默認的對齊方式是右對齊的,而使用了‘-’,就表明要左對齊:
printf("this is /%6d/\n", 65);
printf("this is /%-6d/\n", 65);
輸出:this is / 65/
this is /65 /
‘+’ :打印數字的符號,無論數字是正是負。一般情況下只配合有符號格式說明符使用,比如%+d, %+f;但是%+u、%+c等就會報錯:
printf("this is %+c \n", 65);
輸出:this is +65
‘ ’:這是一個空格,作用和‘+’是相似的,區別就是用空格代替了打印的‘+’;若和‘+’一起使用,由於其優先級較低,效果會被‘+’覆蓋:
printf("this is /% -6d/\n", 65);
輸出:this is / 65 /
可以看到65前面有一個空格。
‘0’:對於所有的數字格式,用前導0而不是空格來填充空白;若指定了整數精度或‘-’,則該標志失效:
printf("this is /%05d/\n", 65);
‘#’:主要用來打印八進制或十六進制的前導符號,偶爾也會配合浮點類型使用:
printf("this is /%#5x/\n", 65);
printf("this is /%#5o/\n", 65);
輸出:this is / 0x41/
this is / 0101/
用於不同數字類型轉換的各個修飾符,它們配合數字類型說明符一起使用:
h: 表示一個short 或 unsigned short ,如 %hd
hh:表示一個signed char 或 unsigned char,如%hhu %hhx
l:表示一個long或unsigned long,如%lo,%ld
ll:long long 或 unsigned long long,%llx
L:long double
t:只能配合整數類型,表示指針之間的差所對應的類型,注意不是指針類型本身,%td
z:只能配合整數類型,表示一個size_t值,即sizeof返回值的類型,%zd