You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言链表程序集成绘图库:将终端打印转为图形展示

为C语言链表程序集成图形化展示功能

选择合适的绘图库

推荐用SDL2,跨平台(Windows/Linux/macOS),API简单直接,适合快速实现简单的图形界面和元素绘制,不需要复杂的UI框架。

集成步骤与代码示例

假设你的链表节点结构如下(可根据实际结构调整):

typedef struct Node {
    int vals[3]; // 对应节点的三元组值,比如[1:3:4]
    struct Node *next;
} Node;

1. 初始化SDL2环境

先完成SDL视频子系统、窗口、渲染器以及字体模块的初始化:

#include <SDL2/SDL.h>
#include <SDL2/SDL_ttf.h> // 用于绘制文本,需链接SDL_ttf库

#define WINDOW_WIDTH 800
#define WINDOW_HEIGHT 400
#define NODE_WIDTH 100
#define NODE_HEIGHT 60
#define PADDING 20

SDL_Window *window = NULL;
SDL_Renderer *renderer = NULL;
TTF_Font *font = NULL;

// 初始化SDL及字体
int init_sdl() {
    if (SDL_Init(SDL_INIT_VIDEO) != 0) {
        fprintf(stderr, "SDL初始化失败: %s\n", SDL_GetError());
        return -1;
    }
    if (TTF_Init() != 0) {
        fprintf(stderr, "SDL_ttf初始化失败: %s\n", TTF_GetError());
        SDL_Quit();
        return -1;
    }
    window = SDL_CreateWindow("链表节点图形展示", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, WINDOW_WIDTH, WINDOW_HEIGHT, 0);
    renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
    // 替换为你系统中存在的字体路径,比如Windows下的C:/Windows/Fonts/arial.ttf
    font = TTF_OpenFont("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", 16);
    if (!window || !renderer || !font) {
        fprintf(stderr, "创建窗口/渲染器/字体失败: %s\n", SDL_GetError());
        cleanup();
        return -1;
    }
    return 0;
}

// 清理SDL资源
void cleanup() {
    if (font) TTF_CloseFont(font);
    if (renderer) SDL_DestroyRenderer(renderer);
    if (window) SDL_DestroyWindow(window);
    TTF_Quit();
    SDL_Quit();
}

2. 编写图形绘制函数

实现单个节点绘制、文本绘制以及节点间箭头连接的功能:

// 绘制文本辅助函数
void draw_text(int x, int y, const char *text, SDL_Color color) {
    SDL_Surface *surface = TTF_RenderText_Solid(font, text, color);
    SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, surface);
    SDL_Rect dest = {x, y, surface->w, surface->h};
    SDL_RenderCopy(renderer, texture, NULL, &dest);
    SDL_FreeSurface(surface);
    SDL_DestroyTexture(texture);
}

// 绘制单个链表节点
void draw_node(Node *node, int x, int y) {
    // 绘制节点矩形框
    SDL_Rect node_rect = {x, y, NODE_WIDTH, NODE_HEIGHT};
    SDL_SetRenderDrawColor(renderer, 0, 128, 255, 255);
    SDL_RenderDrawRect(renderer, &node_rect);
    SDL_SetRenderDrawColor(renderer, 200, 230, 255, 255);
    SDL_RenderFillRect(renderer, &node_rect);

    // 绘制节点的三元组值(居中显示)
    char val_str[32];
    sprintf(val_str, "[%d:%d:%d]", node->vals[0], node->vals[1], node->vals[2]);
    SDL_Color text_color = {0, 0, 0, 255};
    int text_w, text_h;
    TTF_SizeText(font, val_str, &text_w, &text_h);
    draw_text(x + (NODE_WIDTH - text_w)/2, y + (NODE_HEIGHT - text_h)/2, val_str, text_color);
}

// 绘制节点间的连接箭头
void draw_arrow(int start_x, int start_y, int end_x, int end_y) {
    SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
    // 绘制箭头主线
    SDL_RenderDrawLine(renderer, start_x + NODE_WIDTH, start_y + NODE_HEIGHT/2, end_x - PADDING, start_y + NODE_HEIGHT/2);
    // 绘制箭头头部
    int arrow_size = 8;
    SDL_RenderDrawLine(renderer, end_x - PADDING, start_y + NODE_HEIGHT/2, end_x - PADDING - arrow_size, start_y + NODE_HEIGHT/2 - arrow_size);
    SDL_RenderDrawLine(renderer, end_x - PADDING, start_y + NODE_HEIGHT/2, end_x - PADDING - arrow_size, start_y + NODE_HEIGHT/2 + arrow_size);
}

3. 替换原打印循环为图形展示循环

把原来的终端打印逻辑,替换为遍历链表并绘制图形的循环:

void draw_linked_list(Node *head) {
    if (!head) return;

    SDL_Event e;
    int running = 1;
    const int y_pos = (WINDOW_HEIGHT - NODE_HEIGHT)/2; // 节点垂直居中

    while (running) {
        // 处理窗口事件(比如关闭窗口)
        while (SDL_PollEvent(&e)) {
            if (e.type == SDL_QUIT) {
                running = 0;
            }
        }

        // 清空画布
        SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
        SDL_RenderClear(renderer);

        // 遍历链表绘制所有节点和连接箭头
        Node *current = head;
        int current_x = PADDING;
        while (current != NULL) {
            draw_node(current, current_x, y_pos);
            if (current->next != NULL) {
                draw_arrow(current_x, y_pos, current_x + NODE_WIDTH + PADDING, y_pos);
            }
            current_x += NODE_WIDTH + PADDING * 2;
            current = current->next;
        }

        // 更新显示
        SDL_RenderPresent(renderer);
    }
}

4. 编译与运行

Linux下编译命令(需提前安装SDL2和SDL2_ttf开发包):

gcc your_program.c -o linked_list_graph -lSDL2 -lSDL2_ttf

Windows下需配置SDL的头文件和库路径,使用MinGW等工具链时编译参数类似。

注意事项

  • 字体路径:TTF_OpenFont中的路径必须是你系统中存在的字体文件路径,否则文本无法显示。
  • 节点数量适配:如果链表节点过多导致窗口宽度不足,可增大WINDOW_WIDTH,或添加鼠标滚动偏移的逻辑。
  • 资源清理:程序退出前务必调用cleanup()释放SDL资源,避免内存泄漏。

内容的提问来源于stack exchange,提问作者aghozzo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 00:45:39