C语言高级输出及进阶
在C語言中,有三個函數(shù)可以用來在顯示器上輸出數(shù)據(jù),它們分別是:
puts():只能輸出字符串,并且輸出結(jié)束后會自動換行。putchar():只能輸出單個字符。printf():可以輸出各種類型的數(shù)據(jù)。printf() 是最靈活、最復(fù)雜、最常用的輸出函數(shù),完全可以替代 puts() 和 putchar(),我們將重點介紹 printf() 的高級用法。
格式控制符回顧
printf() 的高級用法
printf() 可以有更加炫酷、更加個性、更加整齊的輸出形式。
假如現(xiàn)在老師要我們輸出一個 4×4 的整數(shù)矩陣,為了增強閱讀性,數(shù)字要對齊,怎么辦呢?我們顯然可以這樣做:
#include <stdio.h> int main() {int a1=20, a2=345, a3=700, a4=22;int b1=56720, b2=9999, b3=20098, b4=2;int c1=233, c2=205, c3=1, c4=6666;int d1=34, d2=0, d3=23, d4=23006783;printf("%d %d %d %d\n", a1, a2, a3, a4);printf("%d %d %d %d\n", b1, b2, b3, b4);printf("%d %d %d %d\n", c1, c2, c3, c4);printf("%d %d %d %d\n", d1, d2, d3, d4);return 0; }運行結(jié)果:
20 345 700 22 56720 9999 20098 2 233 205 1 6666 34 0 23 23006783矩陣一般在大學(xué)的《高等數(shù)學(xué)》中會講到,m×n 的數(shù)字矩陣可以理解為把 m×n 個數(shù)字?jǐn)[放成 m 行 n 列的樣子。
看,這是多么地自虐,要敲那么多空格,還要嚴(yán)格控制空格數(shù),否則輸出就會錯位。更加惡心的是,如果數(shù)字的位數(shù)變了,空格的數(shù)目也要跟著變。例如,當(dāng) a1 的值是 20 時,它后面要敲八個空格;當(dāng) a1 的值是 1000 時,它后面就要敲六個空格。每次修改整數(shù)的值,都要考慮修改空格的數(shù)目。
類似的需求隨處可見,整齊的格式會更加美觀,讓人覺得生動有趣。其實,我們大可不必像上面一樣,printf() 可以更好的控制輸出格式。更改上面的代碼:
#include <stdio.h> int main() {int a1=20, a2=345, a3=700, a4=22;int b1=56720, b2=9999, b3=20098, b4=2;int c1=233, c2=205, c3=1, c4=6666;int d1=34, d2=0, d3=23, d4=23006783;printf("%-9d %-9d %-9d %-9d\n", a1, a2, a3, a4);printf("%-9d %-9d %-9d %-9d\n", b1, b2, b3, b4);printf("%-9d %-9d %-9d %-9d\n", c1, c2, c3, c4);printf("%-9d %-9d %-9d %-9d\n", d1, d2, d3, d4);return 0; }輸出結(jié)果:
20 345 700 22 56720 9999 20098 2 233 205 1 6666 34 0 23 23006783這樣寫起來更加方便,即使改變某個數(shù)字,也無需修改 printf() 語句,增加或者減少空格數(shù)目。
**%-9d中,d表示以十進制輸出,9表示最少占9個字符的寬度,寬度不足以空格補齊,-表示左對齊。**綜合起來,%-9d表示以十進制輸出,左對齊,寬度最小為9個字符。大家可以親自試試%9d的輸出效果。
printf() 格式控制符的完整形式如下:
%[flag][width][.precision]type[ ] 表示此處的內(nèi)容可有可無,是可以省略的。
1 . type 表示輸出類型,比如 %d、%f、%c、%lf,type 就分別對應(yīng) d、f、c、lf;再如,%-9d中 type 對應(yīng) d。
type 這一項必須有,這意味著輸出時必須要知道是什么類型。
2 . width 表示最小輸出寬度,也就是至少占用幾個字符的位置;例如,%-9d中 width 對應(yīng) 9,表示輸出結(jié)果最少占用 9 個字符的寬度。
當(dāng)輸出結(jié)果的寬度不足 width 時,以空格補齊(如果沒有指定對齊方式,默認會在左邊補齊空格);當(dāng)輸出結(jié)果的寬度超過 width 時,width 不再起作用,按照數(shù)據(jù)本身的寬度來輸出。
width 的用法:
#include <stdio.h> int main(){int n = 234;float f = 9.8;char c = '@';char *str = "http://www.baidu.com";printf("%10d%12f%4c%8s", n, f, c, str);return 0; }運行結(jié)果:
234 9.800000 @http://www.baidu.com輸出解釋:
n 的指定輸出寬度為 10,234 的寬度為 3,所以前邊要補上 7 個空格。f 的指定輸出寬度為 12,9.800000 的寬度為 8,所以前邊要補上 4 個空格。str 的指定輸出寬度為 8,"http://www.baidu.com" 的寬度為 20,超過了 6,所以指定輸出寬度不再起作用,而是按照 str 的實際寬度輸出。3 . .precision 表示輸出精度,也就是小數(shù)的位數(shù)。
當(dāng)小數(shù)部分的位數(shù)大于 precision 時,會按照四舍五入的原則丟掉多余的數(shù)字;
當(dāng)小數(shù)部分的位數(shù)小于 precision 時,會在后面補 0。
另外,.precision 也可以用于整數(shù)和字符串,但是功能卻是相反的:
用于整數(shù)時,.precision 表示最小輸出寬度。與 width 不同的是,整數(shù)的寬度不足時會在左邊補 0,而不是補空格。用于字符串時,.precision 表示最大輸出寬度,或者說截取字符串。當(dāng)字符串的長度大于 precision 時,會截掉多余的字符;當(dāng)字符串的長度小于 precision 時,.precision 就不再起作用。請看下面的例子:
#include <stdio.h> int main(){int n = 123456;double f = 882.923672;char *str = "abcdefghi";printf("n: %.9d %.4d\n", n, n);printf("f: %.2lf %.4lf %.10lf\n", f, f, f);printf("str: %.5s %.15s\n", str, str);return 0; }運行結(jié)果:
n: 000123456 123456 f: 882.92 882.9237 882.9236720000 str: abcde abcdefghi輸出解說:
對于 n,.precision 表示最小輸出寬度。n 本身的寬度為 6,當(dāng) precision 為 9 時,大于 6,要在 n 的前面補 3 個 0;當(dāng) precision 為 4 時,小于 6,不再起作用。對于 f,.precision 表示輸出精度。f 的小數(shù)部分有 6 位數(shù)字,當(dāng) precision 為 2 或者 4 時,都小于 6,要按照四舍五入的原則截斷小數(shù);當(dāng) precision 為 10 時,大于 6,要在小數(shù)的后面補四個 0。對于 str,.precision 表示最大輸出寬度。str 本身的寬度為 9,當(dāng) precision 為 5 時,小于 9,要截取 str 的前 5 個字符;當(dāng) precision 為 15 時,大于 9,不再起作用。4 . **flag 是標(biāo)志字符。**例如,%#x中 flag 對應(yīng) #,%-9d中 flags 對應(yīng)-。下表列出了 printf() 可以用的 flag:
請看下面的例子:
#include <stdio.h> int main(){int m = 192, n = -943;float f = 84.342;printf("m=%10d, m=%-10d\n", m, m); //演示 - 的用法printf("m=%+d, n=%+d\n", m, n); //演示 + 的用法printf("m=% d, n=% d\n", m, n); //演示空格的用法printf("f=%.0f, f=%#.0f\n", f, f); //演示#的用法return 0; }運行結(jié)果:
m= 192, m=192 m=+192, n=-943 m= 192, n=-943 f=84, f=84.輸出解說:
當(dāng)以%10d輸出 m 時,是右對齊,所以在 192 前面補七個空格;當(dāng)以%-10d輸出 m 時,是左對齊,所以在 192 后面補七個空格。m 是正數(shù),以%+d輸出時要帶上正號;n 是負數(shù),以%+d輸出時要帶上負號。m 是正數(shù),以% d輸出時要在前面加空格;n 是負數(shù),以% d輸出時要在前面加負號。%.0f表示保留 0 位小數(shù),也就是只輸出整數(shù)部分,不輸出小數(shù)部分。默認情況下,這種輸出形式是不帶小數(shù)點的,但是如果有了#標(biāo)志,那么就要在整數(shù)的后面“硬加上”一個小數(shù)點,以和純整數(shù)區(qū)分開。printf() 無法立即輸出
printf() 有一個尷尬的問題,就是有時候不能立即輸出,請看下面的代碼:
#include<stdio.h> #include<unistd.h> int main() {printf("百度");sleep(5); //程序暫停5秒鐘printf("http://www.baidu.com");return 0; }這段代碼使用了兩個 printf() 語句,它們之間有一個 sleep() 函數(shù),該函數(shù)的作用是讓程序暫停 5 秒,然后再繼續(xù)執(zhí)行。sleep() 是 Linux 和 Mac OS 下特有的函數(shù),不能用于 Windows。當(dāng)然,Windows 下也有功能相同的暫停函數(shù),叫做 Sleep()。
我們不妨修改一下代碼,在第一個 printf() 的最后添加一個換行符,如下所示:
printf(“百度\n”);
再次編譯并運行程序,發(fā)現(xiàn)第一個 printf() 首先輸出(程序運行后立即輸出),等待 5 秒以后,第二個 printf() 才輸出。
為什么一個換行符\n就能讓程序的表現(xiàn)有天壤之別呢?按照通常的邏輯,程序運行后第一個 printf() 應(yīng)該立即輸出,而不是等待 5 秒以后再和第二個 printf() 一起輸出,也就是說,第二種情形才符合我們的慣性思維。然而,第一種情形該如何理解呢?
其實,這一切都是輸出緩沖區(qū)(緩存)在作怪!
從本質(zhì)上講,printf() 執(zhí)行結(jié)束以后數(shù)據(jù)并沒有直接輸出到顯示器上,而是放入了緩沖區(qū),直到遇見換行符\n才將緩沖區(qū)中的數(shù)據(jù)輸出到顯示器上。
Windows中的效果,請看下面的代碼:
#include<stdio.h> #include<Windows.h> int main() {printf("百度");Sleep(5000); //程序暫停5秒鐘printf("http://www.baidu.com\n");return 0; }在 Windows 下,想讓程序暫停可以使用 Windows.h 頭文件中的 Sleep() 函數(shù)(S要大寫),它和 Linux 下的 sleep() 功能相同。不過,sleep() 要求的時間單位是秒,而 Sleep() 要求的時間單位是毫秒,1 秒等于 1000 毫秒。這段代碼中,我們要求程序暫停 5000 毫秒,也即 5 秒。
編譯并運行程序,會發(fā)現(xiàn)第一個 printf() 首先輸出(程序運行后立即輸出),等待 5 秒以后,第二個 printf() 才輸出。
在第一個 printf() 的最后添加一個換行符,情況也是一樣的,第一個 printf() 從來不會和第二個 printf() 一起輸出。
綜上所述,Windows 和 Linux、Mac OS 的情況又不一樣。這是因為,Windows 和 Linux、Mac OS 的緩存機制不同。
要想破解 printf() 輸出的問題,必須要了解緩存,它能使你對輸入輸出的認識上升到一個更高的層次,以后不管遇到什么疑難雜癥,都能迎刃而解。可以說,輸入輸出的“命門”就在于緩存。
你的贊是對我最大的支持!!!
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎總結(jié)
以上是生活随笔為你收集整理的C语言高级输出及进阶的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java反射机制是什么?
- 下一篇: 计算平均成绩