一. 前言:
小熙剛才輸出列印快捷鍵的時候,看到有一個 printf 輸出,好奇的試了下,發現和 print 輸出結果是一樣的,都是不換行。但是小熙知道肯定不會有兩個完全一樣的輸出列印,是以又查了下,記錄下。
二. printf介紹:
printf() 原本是 C 語言标準庫函數,用于将格式化後的字元串輸出到标準輸出。
在java中 printf 還是列印, 但是繼承了c語言的一些特性(格式化)
-
注意以下是對 printf 在 java 中使用的簡化,如需檢視更詳細的資訊,請檢視c語言相關介紹。printf("需要格式化的字元串", 輸出表列):
- 需要格式化的字元串的表達式為:
:%[flags][.precision]type
%[标志][.精度]類型
- 辨別:
字元 名稱 說明 - 減号 結果左對齊,右邊填空格。預設是右對齊,左邊填空格。 + 加号 輸出符号(正号或負号) space 空格 輸出值為正時加上空格,為負時加上負号 數字零 将輸出的前面補上0,直到占滿指定列寬為止(不可以搭配使用“-”) - 精度(.precision): 舉例:
.precision 描述 .數值 十進制整數。
(1)對于整型precision不能表示,隻能用辨別中的0表示,不足補前導零,超過不截斷。
(2)對于浮點型,precision表示小數點後數值位數,預設為六位,不足補後置0,超過則截斷。
(3)對于類型說明符g或G,表示可輸出的最大有效數字。
(4)對于字元串,precision表示最大可輸出字元數,不足正常輸出,超過則截斷。
precision不顯示指定,則預設為0
. 以星号代替數值,類似于width中的,在輸出參數清單中指定精度。
結果:System.out.printf("%07d \n",1000); //不足指定寬度補前導0 System.out.printf("%.7f \n",1000.123456789);//超過精度,截斷 System.out.printf("%.7f \n",1000.123456); //不足精度,補後置0 System.out.printf("%.7g \n",1000.123456); //一共的最大有效數字為8位 System.out.printf("%.7s \n","abcdefghij"); //超過指定長度截斷
關于String(本篇的 printf 在 String 的 format方法中同樣适用):0001000 1000.1234568 1000.1234560 1000.123 abcdefg
在 String 中的 format 方法中也是可以使用這裡的精度的,如:String st = String.format("%.2f", 3.141592653); 因為這裡是直接截取,是以不會四舍五入的,如需要請使用DecimalFormat等格式化。
- 類型(基本的):
"%d"是一個int值的占位符, "%f"是一個double 或float值的點位符(預設展示小數點後6位,你也可以通過[width](最小寬度)控制他的占位數,如%.2f是小數點後兩位), "%s"是一個字元串值的點位符的意思, "%c"是一個字元值的點位符的意思
三. 代碼:
- 例子:
/**
* print 和 printf的差別
* printf("需要格式化的字元串", 輸出表列)
* 需要格式化的字元串的表達式為: %[flags][.precision]type
* %[标志][.精度]類型
*
* 此處在pringtf中的使用,在String.format中同樣适用
*/
@Test
public void testPrint(){
int i = 6;
double j = 7;
char c = 'c';
String s = "小熙";
// 單純的格式化輸出,隻是不換行而已
System.out.print("print輸出,i:" + i);
System.out.println();
// printf繼承了c語言的一些特性(格式化)
// 類型:
// "%d"是一個int值的占位符,
// "%f"是一個double 或float值的點位符(預設展示小數點後6位,你也可以通過[width](最小寬度)控制他的占位數,如%.2f是小數點後兩位),
// "%s"是一個字元串值的點位符的意思,
// "%c"是一個字元值的點位符的意思。
System.out.printf("printf輸出,i:%d, j: %.2f, x: %c, s: %s \r\n", i, j, c, s);
System.out.println(String.format("printf輸出,i:%d, j: %.2f, x: %c, s: %s \r\n", i, j, c, s));
System.out.printf("i:%-10d \r\n", i);
System.out.printf("i:%#f", 1.00);
System.out.println("----------------------");
System.out.printf("%07d \n",1000); //不足指定寬度補前導0
System.out.printf("%.7f \n",1000.123456789);//超過精度,截斷
System.out.printf("%.7f \n",1000.123456); //不足精度,補後置0
System.out.printf("%.7g \n",1000.123456); //最大有效數字為8位
System.out.printf("%.7s \n","abcdefghij"); //超過指定長度截斷
}
- 結果
print輸出,i:6
printf輸出,i:6, j: 7.00, x: c, s: 小熙
printf輸出,i:6, j: 7.00, x: c, s: 小熙
i:6
i:1.000000----------------------
0001000
1000.1234568
1000.1234560
1000.123
abcdefg
四. 關于 printf 緩沖:
在 printf 的實作中,在調用 write 之前先寫入 IO 緩沖區,這是一個使用者空間的緩沖。系統調用是軟中斷,頻繁調用,需要頻繁陷入核心态,這樣的效率不是很高,而 printf 實際是向使用者空間的 IO 緩沖寫,在滿足條件的情況下才會調用 write 系統調用,減少 IO 次數,提高效率。
printf(…) 在 glibc 中預設為行緩沖,遇到以下幾種情況會重新整理緩沖區,輸出内容:
(1)緩沖區填滿;
(2)寫入的字元中有換行符\n或回車符\r;
(3)調用 fflush(…) 手動重新整理緩沖區;
(4)調用 scanf(…) 從輸入緩沖區中讀取資料時,也會将輸出緩沖區内的資料重新整理。
可使用setbuf(stdout,NULL)關閉行緩沖,或者setbuf(stdout,uBuff)設定新的緩沖區,uBuff 為自己指定的緩沖區。也可以使用setvbuf(stdout,NULL,_IOFBF,0);來改變标準輸出為全緩沖。全緩沖與行緩沖的差別在于遇到換行符不重新整理緩沖區。
printf(…) 在 VC++ 中預設關閉緩沖區,輸出時會及時輸到螢幕 。如果顯示開啟緩沖區,隻能設定全緩沖。因為微軟閉源,是以無法研究 printf(…) 的實作源碼。
五. 後語:
關于緩沖的部分是借鑒一些在C的描述,以上是小熙在 java 處的簡單實踐,如有更好的建議,也請您提出來。