C语言本身没有内置的“显示屏幕”这个函数,C语言是一门“过程化”的编程语言,它提供了基本的语法、数据类型和控制结构,但它并不知道你的程序运行在什么操作系统上(Windows, Linux, macOS),也不知道你的屏幕是什么样子。

“显示屏幕”这个功能,实际上是通过调用特定操作系统的“应用程序编程接口”(API)来实现的,这意味着,在Windows上和在Linux上实现“显示屏幕”的代码是完全不同的。
下面我将分两种最主流的操作系统来详细解释如何实现。
在 Windows 操作系统上
在Windows上,我们使用的是 Win32 API (Windows 32-bit Application Programming Interface),要显示一些文本或图形到屏幕上,最基本的方式是创建一个“窗口”,然后在这个窗口的“客户区”(Client Area)进行绘制。
最简单的例子:在控制台窗口打印文本
这是最接近“显示”概念的入门方式,但它实际上是在一个黑色的命令行窗口(控制台)中输出。

代码示例:
#include <stdio.h> // 标准输入输出库,提供 printf 函数
int main() {
// printf 函数会将格式化的字符串输出到标准输出(通常是控制台)
printf("Hello, C World!\n");
printf("This is a simple show screen example.\n");
// 为了让窗口停留,等待用户按键
printf("Press Enter to exit...");
getchar(); // 等待用户输入一个字符(按回车)
return 0;
}
如何编译和运行:
- 将代码保存为
hello.c。 - 打开命令提示符(CMD)或 PowerShell。
- 使用 MinGW (GCC) 编译:
gcc hello.c -o hello.exe - 运行生成的程序:
hello.exe - 你会看到一个黑色的窗口出现,显示两行文字,并等待你按回车。
更高级的例子:创建一个图形化窗口并显示文本
这才是真正的“图形界面”显示屏幕,下面的代码会创建一个带标题的白色窗口,并在窗口中央显示 "Hello, Win32 API!"。
代码示例 (win32_screen.c):

#include <windows.h> // Windows API 的头文件
// 窗口过程函数的声明
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
// 1. 注册窗口类
const char* CLASS_NAME = "My Window Class";
WNDCLASS wc = { };
wc.lpfnWndProc = WindowProc; // 窗口过程函数
wc.hInstance = hInstance; // 应用程序实例句柄
wc.lpszClassName = CLASS_NAME; // 窗口类名
wc.hCursor = LoadCursor(NULL, IDC_ARROW); // 加载标准箭头光标
// 注册窗口类
RegisterClass(&wc);
// 2. 创建窗口
HWND hwnd = CreateWindowEx(
0, // 可选的窗口样式
CLASS_NAME, // 窗口类名
"My First Window", // 窗口标题
WS_OVERLAPPEDWINDOW, // 窗口样式
// 窗口位置和大小
CW_USEDEFAULT, CW_USEDEFAULT, 800, 600,
NULL, // 父窗口句柄
NULL, // 菜单句柄
hInstance, // 应用程序实例句柄
NULL // 创建窗口时使用的附加数据
);
if (hwnd == NULL) {
return 0;
}
// 3. 显示窗口
ShowWindow(hwnd, nCmdShow);
// 4. 消息循环
MSG msg = { };
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg); // 翻译键盘消息
DispatchMessage(&msg); // 将消息发送到窗口过程函数
}
return 0;
}
// 窗口过程函数:处理发送到窗口的所有消息
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
switch (uMsg) {
case WM_PAINT: {
// 当窗口需要重绘时(如首次创建、被覆盖后重新显示),此消息被发送
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps); // 获取设备上下文
// 设置文本颜色为黑色
SetTextColor(hdc, RGB(0, 0, 0));
// 设置背景模式为不透明
SetBkMode(hdc, OPAQUE);
// 设置背景颜色为白色
SetBkColor(hdc, RGB(255, 255, 255));
// 在窗口中央绘制文本
const char* text = "Hello, Win32 API!";
RECT rect;
GetClientRect(hwnd, &rect); // 获取窗口客户区大小
// 计算文本位置使其居中
DrawTextA(hdc, text, -1, &rect, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
EndPaint(hwnd, &ps); // 结束绘制
return 0;
}
case WM_DESTROY: {
// 当窗口被销毁时,发送此消息
PostQuitMessage(0); // 发送退出消息
return 0;
}
}
// 对于我们没有处理的消息,交给系统默认处理
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
如何编译和运行:
- 将代码保存为
win32_screen.c。 - 打开 Visual Studio 的 "开发者命令提示"。
- 使用 cl.exe 编译:
cl win32_screen.c user32.lib gdi32.libuser32.lib和gdi32.lib是链接库,包含了创建窗口和绘图所需的函数。
- 运行生成的
win32_screen.exe,你会看到一个白色的窗口,中间有黑色文字。
在 Linux (或 macOS) 操作系统上
在Linux上,我们使用的是 X Window System (简称 X11) API,这是一个更底层的图形系统,现代的Linux桌面环境(如GNOME, KDE)通常建立在X11之上。
最简单的例子:在终端打印文本
和Windows一样,使用 stdio.h 库。
#include <stdio.h>
int main() {
printf("Hello, Linux World!\n");
printf("This is a simple show screen example.\n");
printf("Press Enter to exit...");
getchar();
return 0;
}
编译和运行方式与Windows类似,只是编译器通常是 gcc。
更高级的例子:使用 X11 创建图形化窗口
下面的代码是Linux上使用X11库创建一个窗口并显示文本的例子。
代码示例 (x11_screen.c):
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
Display *dpy;
Window win;
XEvent e;
GC gc;
XFontStruct *font_info;
const char *msg = "Hello, X11!";
int screen_num;
// 1. 连接到X服务器
dpy = XOpenDisplay(NULL);
if (dpy == NULL) {
fprintf(stderr, "Cannot open display\n");
exit(1);
}
screen_num = DefaultScreen(dpy);
// 2. 创建窗口
win = XCreateSimpleWindow(dpy, RootWindow(dpy, screen_num), 10, 10, 800, 600, 1,
BlackPixel(dpy, screen_num), WhitePixel(dpy, screen_num));
// 3. 选择要监听的事件
XSelectInput(dpy, win, ExposureMask | KeyPressMask);
// 4. 映射窗口(显示在屏幕上)
XMapWindow(dpy, win);
// 5. 加载字体(这里使用一个常见的字体)
font_info = XLoadQueryFont(dpy, "-*-fixed-medium-r-*-*-14-*-*-*-*-*-*-*");
if (font_info == NULL) {
fprintf(stderr, "Failed to load font\n");
XCloseDisplay(dpy);
exit(1);
}
// 6. 创建图形上下文
gc = XCreateGC(dpy, win, 0, 0);
XSetFont(dpy, gc, font_info->fid);
// 7. 消息循环
while (1) {
XNextEvent(dpy, &e);
// 绘制事件(当窗口需要重绘时)
if (e.type == Expose) {
XDrawString(dpy, win, gc, 100, 100, msg, strlen(msg));
}
// 键盘按下事件(按任意键退出)
if (e.type == KeyPress) {
break;
}
}
// 8. 清理资源
XFreeFont(dpy, font_info);
XFreeGC(dpy, gc);
XCloseDisplay(dpy);
return 0;
}
如何编译和运行:
- 将代码保存为
x11_screen.c。 - 打开终端。
- 需要链接 X11 库进行编译:
gcc x11_screen.c -o x11_screen -lX11-lX11告诉编译器链接 X11 库。
- 运行程序:
./x11_screen - 你会看到一个窗口,上面有 "Hello, X11!" 的字样,按任意键可以关闭程序。
跨平台解决方案:使用图形库
从上面的例子可以看出,直接使用原生API非常繁琐且代码不通用,为了解决“一次编写,到处运行”的问题,开发者们创建了大量的跨平台图形库。
这些库封装了不同操作系统的底层API,提供了统一的接口。
SDL (Simple DirectMedia Layer)
非常适合游戏开发、多媒体应用,上手简单。
示例概念:
// 伪代码,展示SDL的简洁性
#include <SDL2/SDL.h>
int main() {
SDL_Init(SDL_INIT_VIDEO);
SDL_Window* window = SDL_CreateWindow("SDL Window", ...);
SDL_Renderer* renderer = SDL_CreateRenderer(window, ...);
// 游戏主循环
while (running) {
// 处理事件
// 清空屏幕
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
SDL_RenderClear(renderer);
// 绘制内容
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderDrawLine(renderer, ...); // 画一条线
// 更新屏幕
SDL_RenderPresent(renderer);
}
SDL_Quit();
return 0;
}
GLFW
主要用于创建OpenGL、Vulkan等图形API的上下文和窗口,是3D图形编程的常用选择。
Qt
一个功能非常强大的C++ GUI框架,也提供了C语言绑定,它不仅能做窗口,还能做复杂的用户界面。
| 方法 | 操作系统 | 优点 | 缺点 |
|---|---|---|---|
printf |
All | 简单、通用 | 只能在控制台输出,无法创建图形界面 |
| Win32 API | Windows | 功能强大、与系统集成度高 | 代码复杂、仅限Windows |
| X11 API | Linux/Unix | 功能强大、底层灵活 | 代码复杂、API陈旧、仅限类Unix系统 |
| 图形库 | 跨平台 | 代码可移植、开发效率高、社区支持好 | 需要额外学习库的API、增加程序体积 |
对于初学者,如果你想快速显示一些东西,printf 是最好的起点。
如果你想学习图形界面编程的底层原理,可以尝试Win32 API或X11 API。
如果你想做真正的项目,希望你的代码能在不同操作系统上运行,强烈推荐使用SDL等跨平台图形库。
