这是一个在控制台编程中非常常见但又有些特殊的函数。

getch() 是什么?
getch() 是一个“非缓冲输入”函数,它的全称是 "get character"(获取字符)。
核心特点:
当程序调用 getch() 时,它会立即等待用户按下任意一个键,并且不需要用户按回车键(Enter),一旦用户按下键,getch() 就会立刻返回这个键的值,然后程序继续执行。
这个特性使得 getch() 非常适合制作游戏、菜单选择等需要即时响应的应用程序。
getch() 的工作原理(缓冲 vs. 非缓冲)
为了更好地理解 getch(),我们需要先了解两种输入方式:

a) 缓冲输入
这是 C 语言标准输入(scanf, gets 等)的默认方式。
-
工作流程:
- 用户在键盘上输入字符。
- 字符被暂存到一个称为“输入缓冲区”或“行缓冲区”的内存区域。
- 当用户按下 回车键(Enter) 时,缓冲区中的内容被一次性发送给程序。
scanf或gets等函数从缓冲区中读取数据。
-
缺点:
- 用户必须按回车才能确认输入。
- 如果缓冲区里有残留字符(比如上一次输入留下的),
scanf会直接读取它们,而不会等待新输入。
b) 非缓冲输入
getch() 采用的就是这种方式。

-
工作流程:
- 程序调用
getch()。 - 程序暂停,等待用户按键。
- 用户按下任意一个键(不需要回车)。
getch()立即获取这个键的值,并返回给程序。- 程序继续执行。
- 程序调用
-
优点:
- 即时响应,无需按回车。
- 可以捕获功能键(如 F1, F2)、方向键等特殊按键(需要额外处理)。
如何使用 getch()(重要:包含头文件)
getch() 并不是 C 语言标准库(ANSI C)的一部分,它是一个由特定编译器提供的扩展函数,最常见于 Turbo C++ 和 Borland C++ 编译器,因此在 Windows 平台的 MS-DOS/Windows 控制台环境中被广泛使用。
要使用 getch(),你必须包含头文件 <conio.h>。
示例代码:
#include <stdio.h>
#include <conio.h> // 必须包含这个头文件
int main() {
char ch;
printf("请按任意一个键继续...\n");
// 程序会在这里暂停,直到你按下键盘上的任意一个键
ch = getch(); // 获取你按下的键,并存入变量 ch
printf("\n你按下的键是: %c\n", ch);
printf("该键的 ASCII 码是: %d\n", ch);
return 0;
}
编译和运行:
- 在支持
<conio.h>的旧式编译器(如 Turbo C++)中,可以直接编译运行。 - 在现代编译器(如 GCC、Clang、Visual Studio)中,默认可能不包含这个头文件,你需要特定的环境或库来支持它,在 Windows 上使用 MinGW 或 Visual Studio 的传统控制台项目。
getch() 的常见用途
-
暂停程序执行 这是最常见的用途,让用户看清屏幕上的输出后,按任意键继续。
printf("程序执行完毕。"); getch(); // 暂停,等待用户按键 -
即时菜单选择 不需要用户输入后按回车,直接按一个键就能触发相应功能。
printf("请选择操作: \n"); printf("1. 保存\n"); printf("2. 加载\n"); printf("3. 退出\n"); char choice = getch(); switch (choice) { case '1': printf("保存文件...\n"); break; case '2': printf("加载文件...\n"); break; case '3': printf("退出程序,\n"); break; default: printf("无效选择,\n"); break; } -
游戏开发 在简单的控制台游戏中,用来捕获玩家的按键输入,如移动、跳跃等。
// 伪代码 while (game_is_running) { // ... 游戏逻辑 ... if (kbhit()) { // 检查是否有键被按下(另一个 conio.h 函数) char key = getch(); if (key == 'w') { move_player_up(); } } }
getch() 的相关函数
<conio.h> 头文件中还提供了一些与 getch() 相关的、非常有用的函数:
-
int getche(void);- 功能和
getch()几乎一样,区别在于:getche()会将用户按下的字符 “回显” 到屏幕上(即你能看到你按了什么键)。 getch()是“get character echo”(获取字符并回显)。
- 功能和
-
int kbhit(void);- 这是一个“键盘点击检测”函数。
- 它不等待用户按键,而是立即检查是否有键被按下。
- 如果有键被按下,它返回一个非零值(真);否则返回 0(假)。
- 这个函数对于制作游戏循环非常有用,可以避免程序因等待输入而卡住。
kbhit()和getch()结合使用的经典示例:#include <stdio.h> #include <conio.h> int main() { printf("按 'q' 键退出程序...\n"); while (1) { // 无限循环 if (kbhit()) { // 检查是否有按键 char ch = getch(); // 获取按键 if (ch == 'q' || ch == 'Q') { printf("\n检测到退出指令,程序结束,\n"); break; // 退出循环 } } // 在这里可以放置游戏的主逻辑或动画 printf("."); // 模拟一些后台工作 _sleep(100); // 暂停100毫秒 (Windows.h 中的函数) } return 0; }
跨平台问题与现代替代方案
由于 getch() 是非标准的,代码的可移植性很差,如果你想在现代的、跨平台的 C 项目中实现类似的功能,有以下几种替代方案:
Windows 平台(使用 Windows API)
如果你在 Windows 上开发,可以使用 <windows.h> 中的函数。
#include <stdio.h>
#include <windows.h> // 使用 Windows API
void my_getch() {
// 清空输入缓冲区,防止旧输入干扰
FlushConsoleInputBuffer(GetStdHandle(STD_INPUT_HANDLE));
// 等待单个按键事件
INPUT_RECORD record;
DWORD count;
do {
ReadConsoleInput(GetStdHandle(STD_INPUT_HANDLE), &record, 1, &count);
} while (record.EventType != KEY_EVENT || !record.Event.KeyEvent.bKeyDown);
// 输出按下的字符(类似 getche)
printf("%c", record.Event.KeyEvent.uChar.AsciiChar);
}
int main() {
printf("按任意键继续...");
my_getch();
printf("\n你按下了键,\n");
return 0;
}
Linux / macOS 平台(使用 termios)
在 Unix-like 系统上,可以通过修改终端的属性来实现非缓冲输入。
#include <stdio.h>
#include <termios.h>
#include <unistd.h>
// 保存和恢复终端设置的辅助函数
void set_terminal_mode(int enable) {
static struct termios oldt, newt;
if (enable) {
tcgetattr(STDIN_FILENO, &oldt); // 保存旧设置
newt = oldt;
newt.c_lflag &= ~(ICANON | ECHO); // 关闭规范模式和回显
tcsetattr(STDIN_FILENO, TCSANOW, &newt); // 应用新设置
} else {
tcsetattr(STDIN_FILENO, TCSANOW, &oldt); // 恢复旧设置
}
}
char my_getch() {
char ch;
set_terminal_mode(1); // 设置为非缓冲模式
ch = getchar(); // 读取一个字符
set_terminal_mode(0); // 恢复为默认模式
return ch;
}
int main() {
printf("按任意键继续...");
char ch = my_getch();
printf("\n你按下了键: %c\n", ch);
return 0;
}
| 特性 | getch() |
|---|---|
| 头文件 | <conio.h> (非标准) |
| 功能 | 从控制台获取一个字符,无需按回车。 |
| 响应 | 非缓冲,立即响应。 |
| 回显 | 不回显(按下的字符不会显示在屏幕上)。 |
| 标准性 | 非标准,特定于旧式编译器(如 Turbo C)。 |
| 主要用途 | 暂停程序、即时菜单、游戏输入。 |
| 跨平台 | 差,在现代编译器中通常不可用。 |
对于学习 C 语言基础和了解控制台编程原理,getch() 是一个很好的例子,但在进行实际项目开发时,应优先考虑使用标准库或特定平台的 API 来实现跨平台的即时输入功能。
