printf函式詳解

2021-07-05 05:59:27 字數 3214 閱讀 5808

printf()函式

作用:向終端輸出若干個任意型別的資料(putchar 只能輸出字元,而且只能是乙個字元,而printf可以輸出多個資料,且為任意型別)

一、 printf()的一般格式

printf(格式控制,輸出列表); 例:

int i = 3;

double f = 4.56;

printf("i = %d, f = %f\n", i,f);

printf()是函式,「格式控制」和「輸出列表」是其引數。可以表示為:printf(引數1,                引數2,引數3,....,引數n); 其中「引數1」表示「格式控制」;其餘引數表示「輸出 列表。

二、格式字元

1、d格式符:按十進位制格式輸出。

%d     輸出數字長度為變數數值的實際長度

%md      m指定輸出資料的寬度。當資料本身的實際寬度小於m時,則資料左端補空格;若大於m,則按資料的實際位數輸出。

%ld,%mld     l(小寫字母l)表示輸出「長整型」資料

%0md,%0mld       0(數字0)表示位數不足m時補0

注:%後面的m(

位數控制)、

0(位數不足補

0)對於其他格式符也適用。

例:(□表示空格)

int i = 123;

long j = 123456;

printf("%d□5d□05d,□ld□8ld□08ld",i,i,i,j,j,j);

123□□□123□00123,□123456□□□123456□00123456

2、o(字母)

格式符:按八進位制格式輸出整數。

(不會出現負數格式)

3、x格式符:按十六進製制格式輸出整數。(不會出現負數格式)

4、u格式符:以十進位制數形式輸出

unsigned

的整數。

[例3.2]

main()

a=-1,177777,ffff,65535

b=-2,177776,fffe,65534

5、c格式符:用來輸出乙個字元。乙個整數,其值在0~255之間時也可以以字元的格式輸出     例:

char c;

printf("%c",c);

乙個整數,若其值在0~255範圍內,也可以用字元形式輸出,在輸出前,將該整數轉換為對應的ascii字元。反之,乙個字元資料也可以用整數形式輸出。

[例3.3]

main()

執行結果為:

a,97

a,97

6、s格式符:用來輸出乙個字串。

%s    用來輸出乙個字串,不含雙引號. 例:printf("%s","china");

%ms      m指定寬度(字串長度小於m時左補空格,大於時按實際寬度輸出)

%-ms     左對齊,不足m時右補空格

%m.ns    輸出佔m列,只取字串中左端n個字元.這n各字元輸出在m列的右側,左補空格.

%-m.ns 同上,右補空格

7、f格式符:按實數格式輸出。

%f 整數部分全部顯示出來

,小數部分顯示6位

.但並不是顯示的所有數字都是有效數字

%m.nf    指定資料的寬度共為m列

,其中有

n位小數

.如果數值長度小於

m,則左側補空格。

%-m.nf 與%m.f類似,只是應在右側補空格

[例3.5]

main()

程式輸出:

333333.328152(實數運算中誤差不可避免)

[例3.6]

main()

程式輸出:

3333333333333.3330103333333333333.333010(相同)

從[例3.6]和[例3.7]可以看出:

(1)實數運算中誤差不可避免。

(2)double(例3.7)比float(例3.6)精度高。

(3)float

實數(單精度)的有效位數是

7位,double

實數(雙精度)的有效位數是

16位,超過有效位數的輸出和輸入均無意義。

[例3.7]

main()

輸出結果:

123.455994□□123.455994□□□□□□123.46□□123.46□□123.46

8、e格式符:以指數形式輸出實數。

%e 按規範化指數形式輸出實數,系統自動給出6位小數,指數部分佔5位

%m.ne   與前面的敘述相同

%-m.ne 與前面的敘述相同

9、g格式符:它將根據數值的大小,自動選用f格式或e格式輸出資料,並且它不輸出無意義的0.

三、使用注意

%是printf()的格式說明符,若要直接輸出字元%,在格式控制中使用兩個連續的%。

例: printf("%f%%", 1.0/3)

輸出:0.333333%。

這要從printf的原理講起。

printf執行的時候,將各個引數依次入棧。由於是可變引數,函式體內只能看到第乙個引數,就是字串,在函式內是指標形式。

printf的功能是把這個字串重新組織,也就是字串內列印字元不變,而控制字元用後面的可變引數指示的值代替,最後把重新組織的字串呼叫底層輸出函式輸出。

首先,printf函式對唯一能見的乙個引數取位址,取到的值是棧頂的位址,將該值加乙個整型長度,就得到第乙個可變引數位址。

然後,printf函式對字串中的可列印字元依次入隊,當遇到控制字元的時候,用剛才得到的可變引數的位址(就是棧的一部分)的內容(就是可變引數)去取內容,同時將位址再加乙個整型長度,得到下乙個可變引數位址。

按上面的方法繼續對字串重組,直到重組結束。

現在回頭看你的問題。由於你的引數裡沒有可變引數,但在字串引數裡卻還有控制字元,這時當重組字串遇到控制字元要從可變引數位址取值時,這個位址已經不是printf壓入的引數了!換句話說已經越界了,但由於printf移動的指標不是真正的棧指標,而且只是讀操作不是寫操作,所以不會報錯。

當加了很多控制字元時,搜尋可變引數的指標會不斷後移,那些就更是未知的記憶體區域了。這些和資料段位址、函式位址都沒有關係。

推廣一步,只要控制字元多於可變引數的個數,都會這樣。

至於%p,僅僅是乙個格式控制符。和你的問題完全沒關係,你換成%d、%f等等,都是一樣的結果,當然輸出格式會不同,值是一樣的。

printf函式詳解

printf 格式轉換的一般形式如下 flags width prec type 以括號括起來的引數為選擇性引數,而 與type則是必要的。底下先介紹type的幾種形式 d 整數的引數會被轉成一有符號的十進位制數字 u 整數的引數會被轉成一無符號的十進位制數字 o 整數的引數會被轉成一無符號的八進位...

printf函式詳解

首先直接描述printf函式中的 格式描述串 它是由一系列的 格式轉換說明符號 組成,格式轉換說明符號的描述形式如下 0 m n 輸出精度 形式字母 1 形式字母 制定輸出格式,如表 d 十進位制整型數 i 十進位制整型數 x 十六進製制整型數 o 八進位制整形數 u 無符號十進位制整形數 c 單個...

printf函式詳解

首先直接描述printf函式中的 格式描述串 它是由一系列的 格式轉換說明符號 組成,格式轉換說明符號的描述形式如下 0 m n 輸出精度 形式字母 1 形式字母 制定輸出格式,如表 d 十進位制整型數 i 十進位制整型數 x 十六進製制整型數 o 八進位制整形數 u 無符號十進位制整形數 c 單個...