scanf 和 printf 作為C語(yǔ)言的標(biāo)準(zhǔn)輸入輸出函數(shù),為了提高效率,也是有優(yōu)化的空間的
注意,本頁(yè)面中介紹的讀入和輸出優(yōu)化均針對(duì)整型數(shù)據(jù),若要支持其他類型的數(shù)據(jù)(如浮點(diǎn)數(shù)),可自行按照本頁(yè)面介紹的優(yōu)化原理來(lái)編寫(xiě)代碼。
輸入優(yōu)化:
我們都知道,getchar 是用來(lái)讀入一個(gè)字符的數(shù)據(jù)并將其轉(zhuǎn)換為 char 類型的函數(shù),且速度很快,故可以用“讀入字符-轉(zhuǎn)換為整型”來(lái)代替緩慢的讀入
每個(gè)整數(shù)由兩部分組成——符號(hào)和數(shù)字
整數(shù)的 '+' 通常是省略的,且不會(huì)對(duì)后面數(shù)字所代表的值產(chǎn)生影響,而 '-' 不可省略,因此要進(jìn)行判定
10 進(jìn)制整數(shù)中是不含空格或除 0~9 和正負(fù)號(hào)外的其他字符的,因此在讀入不應(yīng)存在于整數(shù)中的字符(通常為空格)時(shí),就可以判定已經(jīng)讀入結(jié)束
C 和 C++ 語(yǔ)言分別在 ctype.h 和 cctype 頭文件中,提供了函數(shù) isdigit, 這個(gè)函數(shù)會(huì)檢查傳入的參數(shù)是否為十進(jìn)制數(shù)字字符,是則返回 true,否則返回 false。對(duì)應(yīng)的,在下面的代碼中,可以使用 isdigit(ch) 代替 ch >= '0' && ch <= '9',而可以使用 !isdigit(ch) 代替 ch <'0' || ch> '9'
代碼實(shí)現(xiàn):
int read() { int x = 0, w = 1; char ch = 0; while (ch < '0' || ch > '9') // ch 不是數(shù)字時(shí) { if (ch == '-') w = -1; // 判斷是否為負(fù) ch = getchar(); // 繼續(xù)讀入 } while (ch >= '0' && ch <= '9') // ch 是數(shù)字時(shí) { x = x * 10 + (ch - '0'); // 將新讀入的數(shù)字’加’在 x 的后面 // x 是 int 類型,char 類型的 ch 和 ’0’ 會(huì)被自動(dòng)轉(zhuǎn)為其對(duì)應(yīng)的 // ASCII 碼,相當(dāng)于將 ch 轉(zhuǎn)化為對(duì)應(yīng)數(shù)字 // 此處也可以使用 (x<<3)+(x<<1) 的寫(xiě)法來(lái)代替 x*10 ch = getchar(); // 繼續(xù)讀入 } return x * w; // 數(shù)字 * 正負(fù)號(hào) = 實(shí)際數(shù)值 }
輸出優(yōu)化:
同樣,putchar 是用來(lái)輸出單個(gè)字符的函數(shù),因此將數(shù)字的每一位轉(zhuǎn)化為字符輸出以加速。要注意的是,負(fù)號(hào)要單獨(dú)判斷輸出,并且每次 %(mod)取出的是數(shù)字末位,因此要倒序輸出
代碼實(shí)現(xiàn):
int write(int x) { if (x < 0) { // 判負(fù) + 輸出負(fù)號(hào) + 變?cè)瓟?shù)為正數(shù) x = -x; putchar('-'); } if (x > 9) write(x / 10); // 遞歸,將除最后一位外的其他部分放到遞歸中輸出 putchar(x % 10 + '0'); // 已經(jīng)輸出(遞歸)完 x 末位前的所有數(shù)字,輸出末位 }
但是遞歸實(shí)現(xiàn)常數(shù)是較大的,我們可以寫(xiě)一個(gè)棧來(lái)實(shí)現(xiàn)這個(gè)過(guò)程
int write(int x) { static int sta[35]; int top = 0; do { sta[top++] = x % 10, x /= 10; } while (x); while (top) putchar(sta[--top] + 48); // 48 是 '0' }
C語(yǔ)言網(wǎng)提供由在職研發(fā)工程師或ACM藍(lán)橋杯競(jìng)賽優(yōu)秀選手錄制的視頻教程,并配有習(xí)題和答疑,點(diǎn)擊了解:
一點(diǎn)編程也不會(huì)寫(xiě)的:零基礎(chǔ)C語(yǔ)言學(xué)練課程
解決困擾你多年的C語(yǔ)言疑難雜癥特性的C語(yǔ)言進(jìn)階課程
從零到寫(xiě)出一個(gè)爬蟲(chóng)的Python編程課程
只會(huì)語(yǔ)法寫(xiě)不出代碼?手把手帶你寫(xiě)100個(gè)編程真題的編程百練課程
信息學(xué)奧賽或C++選手的 必學(xué)C++課程
藍(lán)橋杯ACM、信息學(xué)奧賽的必學(xué)課程:算法競(jìng)賽課入門課程
手把手講解近五年真題的藍(lán)橋杯輔導(dǎo)課程