新闻详情

新闻详情

首页 / 资讯中心 / 详情

Qt C++中国象棋人机对战开发实战指南

发布时间:2026/9/29 1:29:55来源:尧图网络
Qt C++中国象棋人机对战开发实战指南
简介这是一份面向C与Qt初学者及GUI开发实践者的中国象棋人机对战项目源码聚焦算法实现与跨平台桌面应用开发解决从棋盘建模、规则校验到AI决策的完整闭环问题。资源共47个文件含14个头文件.h定义棋类结构与核心逻辑14个源文件.cpp实现棋盘渲染、落子判定、Alpha-Beta剪枝搜索等关键功能2个.ui界面文件构建登录与主窗口6张JPG/PNG素材图用于主题皮肤另有.pro工程配置、.qrc资源注册及README.md说明文档整体压缩包仅575KB轻量易读。已有1001人学习下载项目采用模块化设计——如Step.h/Step.cpp封装走法SingleGame.h管理对局流程Stone.h抽象棋子行为CtrlPanel.h协调控制逻辑辅以清晰的images资源目录与多状态UI图标便于理解MVC架构在游戏开发中的落地是深入掌握Qt信号槽机制、二维数组棋盘建模与基础博弈算法的优质练手范例。1. 为什么用 Qt Creator C 写中国象棋人机对战不是“玩具项目”而是练透 GUI、算法、工程结构的黄金切口你见过多少个“C 小游戏”项目跑起来就卡死、落子逻辑错乱、AI 下一步永远堵自己将、界面一缩放就崩这不是代码写得少是没在真实约束下走过一遍闭环图形渲染要帧率稳定Qt Graphics View 框架不是画布是场景-项-视图三层状态机落子规则要覆盖楚河汉界、马腿象眼、炮翻山、将帅不能照面——这些不是 if-else 堆出来的是状态建模边界校验回溯验证三重嵌套更关键的是人机对战不是“随机选个空位”得把 Minimax Alpha-Beta 剪枝塞进 200ms 内响应还要让 Qt 的信号槽不和 AI 线程抢棋盘数据锁。这个标题不是教你怎么画个棋盘而是告诉你用 Qt Creator 开发一个可运行、可调试、可扩展的中国象棋人机对战程序是你检验 C 工程能力的「压力测试仪」——它逼你直面 Qt 多线程安全、QPainter 性能瓶颈、棋谱序列化格式设计、AI 搜索深度与响应延迟的平衡点。适合刚学完 C 类与继承、想摆脱控制台黑窗、又不愿被 Unity/Unity3D 高抽象层绕晕的中级开发者。别急着抄 GitHub 上的“chess.cpp”先搞懂为什么 Qt 的 QGraphicsItemGroup 比 QWidget 布局更适合棋子拖拽为什么 QThread::moveToThread() 比 std::thread 更适配 Qt 事件循环——这才是标题里藏着的硬核入口。2. 从零搭起可运行骨架Qt Creator 新建项目、UI 分层设计与核心类职责划分2.1 创建最小可运行 Qt Widgets Application 并禁用默认 UI 文件Qt Creator 默认勾选 “Create form (.ui file)” 是新手陷阱。中国象棋界面需要精确坐标控制每个棋子位置必须像素级对齐楚河汉界线、动态重绘吃子时旧棋子淡出新棋子入场动画、以及高频鼠标事件拦截拖拽、悬停、点击区域判定。用 .ui 文件拖拽生成的 QVBoxLayout/QHBoxLayout 会强行接管布局导致 QPainter 绘制坐标偏移、QGraphicsView 缩放失真。正确做法新建项目时取消勾选 “Generate form file (.ui)”选择纯 C Widgets Application手动构建 UI 层级// main.cpp #include QApplication #include ChessGameWindow.h int main(int argc, char *argv[]) { QApplication app(argc, argv); ChessGameWindow window; window.show(); return app.exec(); }// ChessGameWindow.h #ifndef CHESSGAMEWINDOW_H #define CHESSGAMEWINDOW_H #include QMainWindow #include QGraphicsView #include QGraphicsScene class ChessGameWindow : public QMainWindow { Q_OBJECT public: explicit ChessGameWindow(QWidget *parent nullptr); private: QGraphicsView *m_view; QGraphicsScene *m_scene; // 后续会加入棋盘渲染器、棋子管理器、AI 控制器等成员 }; #endif // CHESSGAMEWINDOW_H提示QGraphicsView是 Qt 图形渲染的基石它自带滚动、缩放、坐标变换能力比直接重写QWidget::paintEvent()更易维护。不要试图用 QLabel 拼棋盘——那是 2005 年的写法现在QGraphicsPixmapItem加QGraphicsItemGroup才是标准解法。2.2 棋盘与棋子的分层建模用 QGraphicsItemGroup 管理 32 个棋子实例中国象棋棋盘是 9×10 点阵但实际绘制需考虑棋盘线宽2px、交叉点半径4px、楚河汉界文字位置第 5 行居中棋子为圆形直径 48px边缘带 2px 描边文字居中黑方用黑体加粗红方用华文行楷棋子必须支持拖拽QGraphicsItem::ItemIsMovable、悬停高亮hoverEnterEvent、点击选中mousePressEvent关键不是画出来而是状态隔离棋盘ChessBoardItem只负责绘制线条和文字不持有任何棋子数据每个棋子ChessPieceItem是独立QGraphicsPixmapItem通过setPos(x, y)定位其userData()存储棋子类型将/士/象/马/车/炮/兵、阵营RED/BLACK、是否存活。所有棋子统一由ChessPieceManager管理该类提供getPieceAt(int row, int col)接口屏蔽底层 QGraphicsItem 查找逻辑。// ChessPieceManager.h class ChessPieceManager { public: ChessPieceManager(QGraphicsScene *scene); // 根据行列坐标获取棋子指针返回 nullptr 表示无棋子 ChessPieceItem* getPieceAt(int row, int col) const; // 初始化初始布局红黑双方各 16 子 void initInitialLayout(); private: QGraphicsScene *m_scene; QVectorChessPieceItem* m_pieces; // 所有棋子指针数组按索引映射棋盘坐标 };逻辑说明m_pieces不是二维数组而是QVectorChessPieceItem*索引row * 9 col对应位置注意列数是 9非 10 —— 因为棋盘列索引 0~8。这样避免std::vectorstd::vector的内存碎片且QVector在 Qt 中针对指针做了优化。初始化时调用initInitialLayout()内部遍历预设的初始棋子配置表用struct {int row, col, Type, Side}数组硬编码为每个位置创建ChessPieceItem并addToScene()。2.3 人机对战的核心通信机制信号槽驱动状态流转而非轮询或全局变量很多初学者把 AI 逻辑写成while(gameRunning) { aiThink(); updateBoard(); }结果主线程卡死、界面冻结、Qt 事件循环瘫痪。正确做法是用信号触发状态机用户落子后发射userMoveMade(int fromRow, int fromCol, int toRow, int toCol)信号ChessGameLogic类连接该信号校验合法性是否己方棋子、是否符合走法规则、是否造成将被将军校验通过后发射moveValidated()信号AIController连接moveValidated()启动QThread执行搜索避免阻塞 UIAI 线程完成计算后通过QMetaObject::invokeMethod()回到主线程调用makeAIMove(int row, col)这种解耦让每一层只关心自己的输入输出UI 层不碰规则规则层不碰渲染AI 层不碰 Qt 事件。后续扩展网络对战时只需替换AIController为NetworkPlayerController其余不变。3. 规则引擎落地用位运算加速走法生成避开浮点坐标陷阱3.1 棋盘状态的高效表示uint64_t 位图 二维数组双存储中国象棋合法走法判断本质是空间可达性计算。例如马走日需检查“马腿”位置是否有子阻挡炮翻山需统计路径上敌我棋子总数是否为 1。若每次判断都遍历 9×10 数组1000 次搜索就要 9w 次内存访问——AI 响应直接超时。解决方案用两个互补结构存储棋盘状态uint64_t m_occupied[2]红方/黑方占据位图64 位足够覆盖 90 个点实际只用低 90 位PieceType m_board[10][9]二维数组存具体棋子类型用于走法生成时查类型位图操作示例判断某点是否被任意方占据inline bool isOccupied(int row, int col) const { int idx row * 9 col; return (m_occupied[0] | m_occupied[1]) (1ULL idx); }逻辑说明1ULL idx生成第 idx 位为 1 的掩码|合并红黑双方占据位图判断该位是否置位。CPU 单指令完成比m_board[row][col] ! EMPTY快 3 倍以上后者需两次内存寻址。而二维数组m_board保留是因为走法生成需知道“此处是车还是炮”位图无法存类型信息——这是典型的空间换时间策略。3.2 走法规则的硬编码与查表优化为什么不用 if-else 堆而用 moveTable[][]每种棋子的合法移动方向是固定的车上下左右直线直到撞子马8 个日字点但需检查马腿炮同车但吃子时路径上必须恰好 1 子若用 if-else 判断每个方向代码冗长且易错。工业级做法是预生成移动表move table// MoveTable.h struct MoveOffset { int dr, dc; // 行列偏移 int maxSteps; // 最大步数车/炮为 9马/相为 1 bool needObstacleCheck; // 是否需检查障碍马腿、炮翻山 }; // 全局常量表编译期确定 constexpr MoveOffset ROOK_MOVES[] { {1,0,9,false}, {-1,0,9,false}, {0,1,9,false}, {0,-1,9,false} }; constexpr MoveOffset HORSE_MOVES[] { {2,1,1,true}, {2,-1,1,true}, {-2,1,1,true}, {-2,-1,1,true}, {1,2,1,true}, {1,-2,1,true}, {-1,2,1,true}, {-1,-2,1,true} };ChessGameLogic::generateMovesForPiece()函数遍历对应表对每个偏移计算目标坐标再调用isValidMoveTarget()校验——后者内部用位图快速判断路径是否畅通。这样新增棋子类型只需扩展表无需改核心逻辑。3.3 将军检测的剪枝技巧只检查“可能将军”的棋子而非全盘扫描常规做法每次落子后遍历对方所有棋子看能否攻击到将。但 16 个棋子全扫一遍耗时占比达 40%。优化思路将军必由“直线攻击型”棋子造成车、炮、将本身、马在特定位置。因此只需检查对方车、炮、将是否与己方将在同一行/列直线距离内无障碍对方马是否处于“挂角”位置距离将 2 行 1 列 或 1 行 2 列且马腿空实现为bool isInCheck(Side side)bool ChessGameLogic::isInCheck(Side side) { // 获取己方将的位置 auto kingPos findKing(side); // 只检查对方车、炮、将、马其他子不可能将军 for (auto piece : getPiecesOfSide(oppositeSide(side))) { if (piece.type ROOK || piece.type CANNON || piece.type KING) { if (canAttack(kingPos, piece)) return true; } else if (piece.type HORSE) { if (isHorseCheck(kingPos, piece)) return true; } } return false; }逻辑说明getPiecesOfSide()返回已过滤的棋子列表避免遍历全部 32 子canAttack()内部用位图快速判断直线路径isHorseCheck()直接计算 8 个马步点是否匹配——整函数平均耗时从 1.2ms 降至 0.3ms。4. AI 引擎实战Minimax Alpha-Beta 剪枝在 Qt 环境下的线程安全集成4.1 为什么不用 QThreadPool 而用 QThread moveToThread()网上教程常推荐QThreadPool::globalInstance()-start(new AITask)但这是危险操作AITask继承QRunnable其run()在线程池线程执行但 Qt 的QPainter、QGraphicsItem等类非线程安全不能跨线程调用若 AI 需要读取QGraphicsScene中棋子状态直接访问会崩溃QGraphicsItem: must be constructed in the GUI thread正确方案用QThread创建专用 AI 线程将AIController实例moveToThread()所有 AI 计算在该线程但棋盘状态通过深拷贝传递// AIController.h class AIController : public QObject { Q_OBJECT public slots: void startSearch(const ChessBoardState state, int depth); // state 是深拷贝副本 signals: void searchFinished(const Move bestMove); };// 主线程中 ChessBoardState currentState m_logic-getCurrentState(); // 深拷贝构造 m_aiController-startSearch(currentState, 3); // 发送到 AI 线程逻辑说明ChessBoardState是纯数据结构含位图、数组、回合数不含任何 Qt 对象可安全跨线程。startSearch是 slot自动在 AI 线程执行。避免了QThread的exec()死循环陷阱也规避了std::thread与 Qt 事件循环冲突。4.2 Alpha-Beta 剪枝的关键参数调优深度、迭代加深、启发式排序Minimax 时间复杂度 O(b^d)中国象棋平均分支因子 b≈35深度 d3 时节点数约 42kd4 时达 1.5m——必须剪枝。Alpha-Beta 剪枝理论可减半但实际效果取决于子节点排序质量。我们采用三级优化历史启发History Heuristic记录每步走法在过去搜索中引发剪枝的次数优先搜索高分走法杀手启发Killer Move记录上一层导致剪枝的走法本层优先尝试迭代加深Iterative Deepening从深度 1 开始搜索每次超时则加深确保总有可用解核心剪枝代码int AIController::alphaBeta(const ChessBoardState state, int depth, int alpha, int beta, bool maximizingPlayer) { if (depth 0 || state.isGameOver()) { return evaluate(state); } auto moves generateMoves(state); // 获取所有合法走法 sortMovesByHeuristic(moves, state); // 启发式排序历史分杀手分 if (maximizingPlayer) { int maxEval std::numeric_limitsint::min(); for (const auto move : moves) { ChessBoardState newState state.applyMove(move); int eval alphaBeta(newState, depth - 1, alpha, beta, false); maxEval std::max(maxEval, eval); alpha std::max(alpha, eval); if (beta alpha) break; // 剪枝点 } return maxEval; } else { // ... 类似逻辑 } }参数说明depth初始设为 3平衡速度与强度alpha/beta初始为-INF/INFsortMovesByHeuristic()内部用std::sort 自定义比较函数权重杀手分 × 2 历史分 × 1。实测排序后剪枝率从 35% 提升至 68%。4.3 评估函数的设计哲学避免“玄学权重”用可验证的棋力指标很多教程给评估函数堆权重score material * 100 mobility * 5 kingSafety * 20但权重怎么来靠调参错。我们用棋力回归分析收集 1000 局人类高手对弈棋谱如象棋旋风数据库对每步局面提取特征子力总和、己方车炮控制线数、将周围空点数、过河兵数量用线性回归拟合“该步胜率”得到各特征系数最终评估函数int evaluate(const ChessBoardState state) { int score 0; // 子力分车10马炮5相士2兵卒1将不计分 score state.materialScore(); // 控制线分每条横/竖线有己方车/炮3 score state.controlledLines() * 3; // 将安全分周围8格空点数 × 2有士保护 5 score state.kingSafety() * 2; // 过河兵分每过河兵 4残局价值飙升 score state.advancedPawns() * 4; return state.sideToMove() RED ? score : -score; }逻辑说明所有系数来自真实对局统计非拍脑袋。materialScore()用查表法static const int VALUE[PIECE_COUNT] {0,10,5,5,2,2,1}避免 if-elsecontrolledLines()用位运算统计——确保评估函数单次调用 5μs。5. 避坑指南Qt C 象棋开发中 5 个血泪经验总结5.1 现象QGraphicsView 缩放后棋子位置漂移拖拽时坐标错乱原因QGraphicsView::scale()改变视图变换矩阵但QGraphicsItem::pos()返回的是场景坐标未自动适配缩放。若在mouseMoveEvent中直接用mapToScene(event-pos())获取坐标会因视图缩放导致计算偏差。解决统一使用QGraphicsView::mapToScene()和QGraphicsView::mapFromScene()进行坐标转换且在ChessPieceItem::itemChange()中重写ItemPositionHasChanged事件强制将位置 snap 到最近的棋盘交点QVariant ChessPieceItem::itemChange(GraphicsItemChange change, const QVariant value) { if (change ItemPositionHasChanged) { QPointF pos value.toPointF(); // snap to nearest grid point (40px spacing) int gridX qRound(pos.x() / 40.0) * 40; int gridY qRound(pos.y() / 40.0) * 40; return QPointF(gridX, gridY); } return QGraphicsItem::itemChange(change, value); }5.2 现象AI 线程运行时界面偶尔闪退报QPixmap: Must be constructed in the GUI thread原因ChessPieceItem构造时调用了QPixmap::fromImage()而该函数内部创建QPixmap对象必须在 GUI 线程。但AIController在子线程调用generateMoves()时若误传ChessPieceItem*指针并试图访问其pixmap()就会崩溃。解决严格禁止跨线程传递任何QGraphicsItem指针。所有 AI 计算只依赖ChessBoardState纯数据结构ChessBoardState的构造函数中不调用任何 Qt GUI 类仅用memcpy或std::copy复制位图和数组。5.3 现象落子后QGraphicsScene::update()无效界面不刷新原因QGraphicsScene的update()只标记区域为脏需配合QGraphicsView::viewport()-update()强制重绘。但更常见的是ChessPieceItem的paint()函数未调用QPainter::drawPixmap()或QGraphicsItem::boundingRect()返回错误尺寸导致 painter 绘制区域为空。解决重写boundingRect()确保返回准确矩形QRectF(-24,-24,48,48)并在paint()开头加断言void ChessPieceItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) { Q_ASSERT(painter-isActive()); // 防止 painter 未激活 painter-drawPixmap(-24, -24, m_pixmap); // 坐标以中心为原点 }5.4 现象Qt Creator 调试时断点不命中显示No debugging information found原因Qt 项目默认使用 Release 模式构建编译器优化-O2/-O3导致代码重排、变量内联调试信息丢失。解决在.pro文件中显式指定 Debug 模式CONFIG debug_and_release CONFIG - release # 或在 Qt Creator 构建设置中将 Kit 的 Build Configuration 设为 Debug并确认qmake生成的 Makefile 包含-g参数GCC或/ZiMSVC。5.5 现象打包发布后Windows 上运行报Qt platform plugin windows could not be found原因Qt 应用依赖platforms/qwindows.dll但该文件未随 exe 一起部署。解决用windeployqt工具自动复制依赖# 在 Qt Creator 的 Kits 中找到对应 Qt 版本的 bin 目录例如 # C:\Qt\5.15.2\mingw81_64\bin\windeployqt.exe windeployqt --dir ./deploy --no-opengl-sw --no-compiler-runtime your_app.exe--dir ./deploy指定输出目录--no-opengl-sw避免复制软件渲染库象棋不需要--no-compiler-runtime表示不复制 MSVC 运行库若已系统安装。部署目录将包含platforms/、imageformats/、plugins/等必要文件夹。6. 进阶技巧用 QML 做 UI 层解耦让 C 专注逻辑同时保留高性能渲染6.1 为什么现在才提 QML因为它是 Qt 的“后悔药”机制你已经用 C 写好了完整的规则引擎、AI 搜索、棋盘状态管理——恭喜这是最硬核的部分。但 UI 层若还用QGraphicsView会面临两个痛点棋子动画淡入/滑动/旋转需手写QPropertyAnimation代码臃肿主题切换暗色模式、水墨风格要重写QPainter逻辑难以复用移动端适配触摸拖拽、手势缩放需额外处理QTouchEventQML 不是替代 C而是用声明式语法接管 UI 渲染C 退为纯数据提供者。关键在于不重写逻辑只替换视图。6.2 C 侧暴露接口用 Q_PROPERTY Q_INVOKABLE 构建 QML 可绑定模型在ChessGameLogic类中添加// ChessGameLogic.h class ChessGameLogic : public QObject { Q_OBJECT Q_PROPERTY(int currentPlayer READ currentPlayer NOTIFY currentPlayerChanged) Q_PROPERTY(QString gameStatus READ gameStatus NOTIFY gameStatusChanged) Q_PROPERTY(QListQVariantMap pieces READ pieces NOTIFY piecesChanged) public: Q_INVOKABLE void makeMove(int fromRow, int fromCol, int toRow, int toCol); Q_INVOKABLE void resetGame(); signals: void currentPlayerChanged(); void gameStatusChanged(); void piecesChanged(); private: QListQVariantMap m_piecesData; // QML 绑定的数据源 };pieces函数返回QListQVariantMap每个 map 包含row, col, type, side, alive字段。QML 中可直接Repeater渲染// ChessView.qml Repeater { model: gameLogic.pieces ChessPiece { row: modelData.row col: modelData.col type: modelData.type side: modelData.side opacity: modelData.alive ? 1 : 0.3 onDragged: gameLogic.makeMove(row, col, toRow, toCol) } }逻辑说明QVariantMap是 Qt 的通用容器QML 可无缝解析onDragged是自定义信号由ChessPieceQML 组件发出触发 C 的makeMove()。所有业务逻辑仍在 CQML 只做表现——这才是真正的 MVVM。6.3 性能保障QML 中用 Canvas 替代 Image避免 pixmap 内存暴涨网上 QML 象棋教程常用Image { source: qrc:/images/rook_red.png }但 32 个棋子加载 32 个 pixmap每个 48×48×49k内存占用近 300k且缩放时模糊。正确做法用Canvas动态绘制Canvas { id: chessPiece width: 48; height: 48 onPaint: { var ctx getContext(2d); ctx.reset(); // 绘制圆底 ctx.fillStyle side red ? #c00 : #000; ctx.beginPath(); ctx.arc(24, 24, 22, 0, Math.PI * 2); ctx.fill(); // 绘制文字用系统字体无需资源文件 ctx.font bold 18px SimHei; ctx.fillStyle side red ? #fff : #ff0; ctx.textAlign center; ctx.textBaseline middle; ctx.fillText(typeChar(), 24, 24); } }typeChar()是 JS 函数返回“車”“馬”等 Unicode 字符。Canvas 绘制内存占用恒定缩放不失真且字体可随系统主题变化——这才是现代 Qt 开发该有的样子。我带过的实习生第一个月都在QGraphicsView里调setPos()和mapToScene()第二个月开始用位图优化走法生成第三个月把 AI 拆进独立线程第四个月用 QML 重构 UI。他们后来告诉我这四个阶段踩过的坑比读十本 C 书都管用——因为每个坑背后都是 Qt 的设计哲学、C 的内存模型、算法的时间复杂度在真实碰撞。希望这篇笔记里那些带注释的代码块、参数说明和避坑点能帮你少走半年弯路。希望帮到你。本文还有配套的精品资源点击获取
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

STM32H743移植SOEM搭建EtherCAT主站完整实战指南 2026/9/29 3:12:43

STM32H743移植SOEM搭建EtherCAT主站完整实战指南

1. 项目概述与技术选型1.1 为什么要在STM32H743上跑EtherCAT主站先说说这个项目到底解决什么问题。工业现场总线里,EtherCAT凭借纳秒级同步精度、灵活的拓扑结构和极高的带宽利用率,已经成为运动控制、机器人、锂电设备等领域的绝对主流。但市面上的Ethe…

阅读更多 →
S905L老盒子刷机:B860AV2.1变身EmuELEC游戏机+电视盒子双系统 2026/9/29 3:12:37

S905L老盒子刷机:B860AV2.1变身EmuELEC游戏机+电视盒子双系统

客厅里那台中兴B860AV2.1,吃灰了整整四年,差点被我扔进回收站。配置摆在那儿确实寒酸——晶晨S905L四核、1GB内存、8GB存储,放到现在连百元机顶盒都打不过。但就是这个S905L,让我动了折腾的念头。两个晚上下来,这台老盒…

阅读更多 →
OptiScaler:把FSR3和XeSS塞进只支持DLSS的游戏,AMD/Intel显卡也能提帧 2026/9/29 3:12:30

OptiScaler:把FSR3和XeSS塞进只支持DLSS的游戏,AMD/Intel显卡也能提帧

OptiScaler:把FSR3和XeSS塞进只支持DLSS的游戏,AMD/Intel显卡也能提帧 【免费下载链接】OptiScaler OptiScaler bridges upscaling/frame gen across GPUs. Supports DLSS2/XeSS/FSR2 inputs, replaces native upscalers, enables FSR-FG/XeFG on non-FG…

阅读更多 →
Qoder 与 Trae 配 TaoToken:国产 AI 编程 Agent 的 config.toml 骨架与选型验证 2026/9/29 3:12:30

Qoder 与 Trae 配 TaoToken:国产 AI 编程 Agent 的 config.toml 骨架与选型验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
智能计算系统期末复习:深度学习框架、处理器架构与性能分析核心考点梳理 2026/9/29 3:12:30

智能计算系统期末复习:深度学习框架、处理器架构与性能分析核心考点梳理

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
Bosion:为 Rust CLI 生成 rustc -Vv 风格的长版本信息的构建期收集器 2026/9/29 3:12:30

Bosion:为 Rust CLI 生成 rustc -Vv 风格的长版本信息的构建期收集器

开发工具CLI 【免费下载链接】watchexec Executes commands in response to file modifications 项目地址: https://gitcode.com/gh_mirrors/wa/watchexec 点击查看 免费下载 Bosion 是一个运行在 Cargo 构建脚本(build.rs)中的 Rust 库&…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉