本文介紹兩個以 K 開頭的經典 DOS 時代 C 函數:kbhit() 用於非阻塞鍵盤檢測,keep() 用於建立常駐記憶體程式 (TSR),附完整語法與實戰範例。
功能:若鍵盤緩衝區有待讀取字元則傳回非零值,否則傳回 0。不會等待使用者輸入,適合遊戲迴圈或即時監控。
原型:
int kbhit(void);
標頭檔:<conio.h>
範例:等待使用者按鍵繼續
#include <conio.h>
#include <stdio.h>
int main(void) {
cprintf("Press any key to continue:");
while (!kbhit()) {
/* 執行背景工作,例如更新動畫、輪詢感測器 */
}
cprintf("\r\nA key was pressed...\r\n");
getch(); // 實際讀取字元,清空緩衝區
return 0;
}
注意:kbhit() 僅檢查狀態,必須搭配 getch() 或 getche() 取走字元,否則下一次呼叫仍會傳回真值。
功能:讓程式以「終止並常駐」方式結束,釋放環境區塊但保留程式碼與資料於記憶體,常用於中斷服務常式 (ISR)、熱鍵工具、背景列印機等。
原型:
void keep(int status, int size);
參數
status:傳回給 DOS 的錯誤代碼 (通常為 0)。size:要保留的記憶體段落數 (1 段落 = 16 位元組),計算公式通常為 (_SS + (_SP/16) - _psp)。完整 TSR 範例:時鐘滴答顯示計數器
/***
* 注意:編譯時必須關閉「Test Stack Overflow」選項,
* 否則產生的 .EXE 無法正常常駐。
*/
#include <dos.h>
#include <stdio.h>
#define INTR 0x1C // 時鐘滴答中斷向量
#define ATTR 0x7900 // 灰底藍字屬性
extern unsigned _heaplen = 1024; // 縮小堆疊與堆積以減少常駐體積
extern unsigned _stklen = 512;
void interrupt (*oldhandler)(void);
void interrupt handler(void) {
unsigned int far *screen = MK_FP(0xB800, 0); // 彩色文字模式影像緩衝區
static int count = 0;
count = (count + 1) % 10;
screen[0][79] = count + '0' + ATTR; // 螢幕右上角顯示 0-9 循環
oldhandler(); // 連結原有中斷處理常式
}
int main(void) {
oldhandler = getvect(INTR); // 保存原中斷向量
setvect(INTR, handler); // 安裝新處理常式
// 計算需保留段落數並常駐
keep(0, (_SS + (_SP / 16) - _psp));
return 0; // 實際不會執行到這裡
}
關鍵點總結
printf)。keep() 而非 exit()。