天天看點

java中的print和printf的差別

一. 前言:

小熙剛才輸出列印快捷鍵的時候,看到有一個 printf 輸出,好奇的試了下,發現和 print 輸出結果是一樣的,都是不換行。但是小熙知道肯定不會有兩個完全一樣的輸出列印,是以又查了下,記錄下。

二. printf介紹:

printf() 原本是 C 語言标準庫函數,用于将格式化後的字元串輸出到标準輸出。

在java中 printf 還是列印, 但是繼承了c語言的一些特性(格式化)

  1. printf("需要格式化的字元串", 輸出表列):

    注意以下是對 printf 在 java 中使用的簡化,如需檢視更詳細的資訊,請檢視c語言相關介紹。
  2. 需要格式化的字元串的表達式為:

    %[flags][.precision]type

    :

    %[标志][.精度]類型

  3. 辨別:
    字元 名稱 說明
    - 減号 結果左對齊,右邊填空格。預設是右對齊,左邊填空格。
    + 加号 輸出符号(正号或負号)
    space 空格 輸出值為正時加上空格,為負時加上負号
    數字零 将輸出的前面補上0,直到占滿指定列寬為止(不可以搭配使用“-”)
  4. 精度(.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");	//超過指定長度截斷
               
    結果:
    0001000 
         1000.1234568 
         1000.1234560 
         1000.123 
          abcdefg 
               
    關于String(本篇的 printf 在 String 的 format方法中同樣适用):
    在 String 中的 format 方法中也是可以使用這裡的精度的,如:String st = String.format("%.2f", 3.141592653);
        因為這裡是直接截取,是以不會四舍五入的,如需要請使用DecimalFormat等格式化。
               
  5. 類型(基本的):
    "%d"是一個int值的占位符,
       "%f"是一個double 或float值的點位符(預設展示小數點後6位,你也可以通過[width](最小寬度)控制他的占位數,如%.2f是小數點後兩位),
       "%s"是一個字元串值的點位符的意思,
       "%c"是一個字元值的點位符的意思
               

三. 代碼:

  1. 例子:
/**
     * 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");	//超過指定長度截斷

    }
           
  1. 結果
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 處的簡單實踐,如有更好的建議,也請您提出來。