1. 引言

介于身边有特别多没有学习过编程,或者有一定C语言、python或是Java基础的但是没有接触过C++的新手朋友,我想可以通过一个很简单的小项目作为挑战,帮助大家入门C++。

今天,我们将挑战一个对新手来说稍微复杂一点,但非常适合新手的经典小游戏——**井字棋 **!通过这个项目,你将学习到 C++ 中更重要的概念,让你的编程能力再上一个台阶!

这个项目将带你:

  • 深入理解函数: 如何定义、调用函数,以及参数传递(包括引用传递)。
  • 掌握二维数据结构: 使用 std::vector 来模拟棋盘。
  • 设计更复杂的程序逻辑: 判断输赢、平局等游戏状态。
  • 提升代码组织能力: 将不同功能封装到独立的函数中。

如何学习
在编写的过程中可能会遇到之前没有接触过的知识点,这时候不要只是跟着案例敲,一个优秀的程序员应该理解自己所写的代码,而不是一味地对着抄,或是复制粘贴。对于不懂的代码:

  • 使用AI工具(例如deepseek)解读
  • 查阅相关手册或博客文章

准备好了吗?让我们开始这场新的编程冒险吧!

2. 项目概览:井字棋游戏

游戏规则:

  1. 井字棋在 3x3 的棋盘上进行。
  2. 两名玩家轮流落子,一个用 ‘X’,一个用 ‘O’。
  3. 玩家选择一个空位进行落子(通常通过输入行和列的数字)。
  4. 第一个在横线、竖线或对角线上连成三个自己的棋子的玩家获胜。
  5. 如果棋盘填满,但没有人获胜,则游戏平局。

游戏界面示例(命令行):

 1 | 2 | 3
---+---+---4 | 5 | 6
---+---+---7 | 8 | 9玩家 X 的回合。请输入你的选择 (1-9):

3. 环境准备

你需要:

  1. 一个 C++ 编译器: GCC (MinGW)、MSVC (Visual Studio)、Clang 等。(如果不知道什么是编译器记得先简单了解一下)
  2. 一个代码编辑器或 IDE: VS Code、Visual Studio、CLion 等。(推荐:Visual Studio)

VisualStudio2022使用教程与安装
确保你的环境能够编译和运行 C++ 程序。

4. 逐步实现:井字棋游戏

我们将把游戏的不同功能拆分成独立的函数,这样代码会更清晰、更容易维护。

4.1 核心数据结构:棋盘

井字棋棋盘是一个 3x3 的网格。在 C++ 中,我们可以使用二维 std::vector 来表示它。std::vector 是 C++ 标准库提供的动态数组,比 C 风格数组更安全、更灵活。

#include <iostream> // 用于输入输出
#include <vector>   // 用于 std::vector
#include <limits>   // 用于 std::numeric_limits (处理输入错误)// 为了方便,我们在这里使用整个 std 命名空间
using namespace std;// 定义棋盘
// vector<vector<char>> 表示一个二维字符向量
// 初始时,每个格子都用 ' ' (空格) 表示空位
vector<vector<char>> board = {{' ', ' ', ' '},{' ', ' ', ' '},{' ', ' ', ' '}
};// 当前玩家 ('X' 或 'O')
char currentPlayer = 'X';// 游戏是否结束
bool gameOver = false;int main() {// 游戏主逻辑将在这里实现return 0;
}
4.2 函数一:显示棋盘 displayBoard()

这个函数负责将当前的棋盘状态打印到控制台,让玩家看到。

// 函数:显示棋盘
void displayBoard() {system("cls"); // Windows 清屏命令,Linux/macOS 可以用 system("clear");// 或者注释掉,不清屏也行cout << "--- 井字棋 ---" << endl;cout << "-------------" << endl;for (int i = 0; i < 3; ++i) {for (int j = 0; j < 3; ++j) {cout << " " << board[i][j]; // 打印棋子if (j < 2) {cout << " |"; // 打印列分隔符}}cout << endl;if (i < 2) {cout << "---+---+---" << endl; // 打印行分隔符}}cout << "-------------" << endl;
}
4.3 函数二:玩家落子 playerMove()

这个函数负责接收玩家的输入,并更新棋盘。它需要处理用户输入、检查输入是否合法(是否在范围内、是否为空位)。

// 函数:玩家落子
// 参数 board 用引用传递 (&),这样函数内部对 board 的修改会直接反映到外部的 board 变量
void playerMove(vector<vector<char>>& currentBoard, char player) {int choice;int row, col;while (true) {cout << "玩家 " << player << " 的回合。请输入你的选择 (1-9): ";cin >> choice;// 检查输入是否为数字,以及是否在有效范围内if (cin.fail() || choice < 1 || choice > 9) {cout << "无效输入!请输入 1 到 9 之间的数字。" << endl;cin.clear(); // 清除错误标志// 忽略输入缓冲区中剩余的字符,直到换行符cin.ignore(numeric_limits<streamsize>::max(), '\n');continue; // 继续循环,要求重新输入}// 将 1-9 的选择转换为二维数组的行和列row = (choice - 1) / 3;col = (choice - 1) % 3;// 检查选择的格子是否为空if (currentBoard[row][col] == ' ') {currentBoard[row][col] = player; // 落子break; // 输入合法,跳出循环} else {cout << "这个位置已经被占用了!请选择其他位置。" << endl;}}
}

新知识点:

  • 引用传递 (&): playerMove(vector<vector<char>>& currentBoard, char player) 中的 & 符号表示 currentBoard 是一个引用。这意味着函数内部对 currentBoard 的修改,会直接影响到 main 函数中传入的 board 变量,而不是它的一个副本。这对于需要修改外部变量的函数非常有用。
  • cin.fail()cin.clear() 用于处理非数字输入错误。cin.fail() 检查输入流是否处于错误状态,cin.clear() 清除错误标志,cin.ignore() 丢弃错误输入。
  • numeric_limits<streamsize>::max() 表示流的最大尺寸,配合 cin.ignore 丢弃所有剩余输入。
4.4 函数三:检查胜利 checkWin()

这个函数判断当前棋盘上是否有玩家获胜。

// 函数:检查是否有玩家获胜
// 参数 currentBoard 用常量引用传递 (const &),表示函数只读取 board 的内容,不修改它
bool checkWin(const vector<vector<char>>& currentBoard, char player) {// 检查行for (int i = 0; i < 3; ++i) {if (currentBoard[i][0] == player && currentBoard[i][1] == player && currentBoard[i][2] == player) {return true;}}// 检查列for (int j = 0; j < 3; ++j) {if (currentBoard[0][j] == player && currentBoard[1][j] == player && currentBoard[2][j] == player) {return true;}}// 检查主对角线if (currentBoard[0][0] == player && currentBoard[1][1] == player && currentBoard[2][2] == player) {return true;}// 检查副对角线if (currentBoard[0][2] == player && currentBoard[1][1] == player && currentBoard[2][0] == player) {return true;}return false; // 没有获胜
}

新知识点:

  • 常量引用 (const &): checkWin(const vector<vector<char>>& currentBoard, char player) 中的 const & 表示 currentBoard 是一个引用,但函数内部不能修改 currentBoard 的内容。这是一种很好的编程习惯,既避免了不必要的拷贝,又保证了数据的安全性。
  • bool 返回值: 函数返回 truefalse,表示是否获胜。
4.5 函数四:检查平局 checkDraw()

这个函数判断棋盘是否已满,且没有玩家获胜。

// 函数:检查是否平局
bool checkDraw(const vector<vector<char>>& currentBoard) {for (int i = 0; i < 3; ++i) {for (int j = 0; j < 3; ++j) {if (currentBoard[i][j] == ' ') {return false; // 还有空位,不是平局}}}return true; // 没有空位,是平局
}
4.6 游戏主逻辑 main()

现在,我们将所有函数组合起来,构建游戏的主循环。

int main() {cout << "-----------------------------------" << endl;cout << "         欢迎来到井字棋!        " << endl;cout << "-----------------------------------" << endl;// 游戏主循环while (!gameOver) {displayBoard(); // 显示棋盘// 玩家落子playerMove(board, currentPlayer);// 检查胜利if (checkWin(board, currentPlayer)) {displayBoard(); // 胜利后再次显示最终棋盘cout << "恭喜玩家 " << currentPlayer << " 获胜!" << endl;gameOver = true; // 游戏结束}// 检查平局(只有在没有胜利者的情况下才检查平局)else if (checkDraw(board)) {displayBoard(); // 平局后显示最终棋盘cout << "游戏平局!" << endl;gameOver = true; // 游戏结束}// 切换玩家else {currentPlayer = (currentPlayer == 'X') ? 'O' : 'X'; // 三元运算符:如果当前是X,则切换到O,否则切换到X}}cout << "游戏结束!感谢游玩!" << endl;return 0;
}

5. 完整代码

现在,将所有代码片段组合起来,你的 main.cpp 文件应该长这样:

#include <iostream> // 用于标准输入输出
#include <vector>   // 用于 std::vector
#include <limits>   // 用于 std::numeric_limits (处理输入错误)
#include <string>   // 用于 std::string (如果需要)
// #include <windows.h> // 如果使用 system("cls") 且在 Windows 环境下// 为了方便,我们在这里使用整个 std 命名空间
using namespace std;// 定义棋盘 (全局变量,简化示例)
vector<vector<char>> board = {{' ', ' ', ' '},{' ', ' ', ' '},{' ', ' ', ' '}
};// 当前玩家 ('X' 或 'O')
char currentPlayer = 'X';// 游戏是否结束
bool gameOver = false;// --- 函数声明 (良好的编程习惯,先声明再定义) ---
void displayBoard();
void playerMove(vector<vector<char>>& currentBoard, char player);
bool checkWin(const vector<vector<char>>& currentBoard, char player);
bool checkDraw(const vector<vector<char>>& currentBoard);// --- 函数定义 ---// 函数:显示棋盘
void displayBoard() {// Windows 清屏命令,Linux/macOS 可以用 system("clear");// 如果不想清屏,可以注释掉这行// system("cls"); cout << "\n--- 井字棋 ---" << endl;cout << "-------------" << endl;for (int i = 0; i < 3; ++i) {for (int j = 0; j < 3; ++j) {cout << " " << board[i][j]; // 打印棋子if (j < 2) {cout << " |"; // 打印列分隔符}}cout << endl;if (i < 2) {cout << "---+---+---" << endl; // 打印行分隔符}}cout << "-------------" << endl;
}// 函数:玩家落子
void playerMove(vector<vector<char>>& currentBoard, char player) {int choice;int row, col;while (true) {cout << "玩家 " << player << " 的回合。请输入你的选择 (1-9): ";cin >> choice;// 检查输入是否为数字,以及是否在有效范围内if (cin.fail() || choice < 1 || choice > 9) {cout << "无效输入!请输入 1 到 9 之间的数字。" << endl;cin.clear(); // 清除错误标志// 忽略输入缓冲区中剩余的字符,直到换行符cin.ignore(numeric_limits<streamsize>::max(), '\n');continue; // 继续循环,要求重新输入}// 将 1-9 的选择转换为二维数组的行和列// 1 -> (0,0), 2 -> (0,1), 3 -> (0,2)// 4 -> (1,0), 5 -> (1,1), 6 -> (1,2)// 7 -> (2,0), 8 -> (2,1), 9 -> (2,2)row = (choice - 1) / 3;col = (choice - 1) % 3;// 检查选择的格子是否为空if (currentBoard[row][col] == ' ') {currentBoard[row][col] = player; // 落子break; // 输入合法,跳出循环} else {cout << "这个位置已经被占用了!请选择其他位置。" << endl;}}
}// 函数:检查是否有玩家获胜
bool checkWin(const vector<vector<char>>& currentBoard, char player) {// 检查行for (int i = 0; i < 3; ++i) {if (currentBoard[i][0] == player && currentBoard[i][1] == player && currentBoard[i][2] == player) {return true;}}// 检查列for (int j = 0; j < 3; ++j) {if (currentBoard[0][j] == player && currentBoard[1][j] == player && currentBoard[2][j] == player) {return true;}}// 检查主对角线 (左上到右下)if (currentBoard[0][0] == player && currentBoard[1][1] == player && currentBoard[2][2] == player) {return true;}// 检查副对角线 (右上到左下)if (currentBoard[0][2] == player && currentBoard[1][1] == player && currentBoard[2][0] == player) {return true;}return false; // 没有获胜
}// 函数:检查是否平局
bool checkDraw(const vector<vector<char>>& currentBoard) {for (int i = 0; i < 3; ++i) {for (int j = 0; j < 3; ++j) {if (currentBoard[i][j] == ' ') {return false; // 还有空位,不是平局}}}return true; // 没有空位,是平局
}int main() {cout << "-----------------------------------" << endl;cout << "         欢迎来到井字棋!        " << endl;cout << "-----------------------------------" << endl;// 游戏主循环while (!gameOver) {displayBoard(); // 显示棋盘// 玩家落子playerMove(board, currentPlayer);// 检查胜利if (checkWin(board, currentPlayer)) {displayBoard(); // 胜利后再次显示最终棋盘cout << "恭喜玩家 " << currentPlayer << " 获胜!" << endl;gameOver = true; // 游戏结束}// 检查平局(只有在没有胜利者的情况下才检查平局)else if (checkDraw(board)) {displayBoard(); // 平局后显示最终棋盘cout << "游戏平局!" << endl;gameOver = true; // 游戏结束}// 切换玩家else {// 三元运算符:如果当前是X,则切换到O,否则切换到XcurrentPlayer = (currentPlayer == 'X') ? 'O' : 'X';}}cout << "游戏结束!感谢游玩!" << endl;return 0; // 程序正常退出
}

6. 编译和运行你的游戏

6.1 使用命令行编译 (以 GCC 为例)
  1. 打开你的命令行工具(Windows 下可以是 Git Bash、CMD、PowerShell,macOS/Linux 下是 Terminal)。

  2. 使用 cd 命令进入你存放 main.cpp 的文件夹。

    cd path/to/your/TicTacToeGame
    
  3. 编译 main.cpp

    g++ main.cpp -o tictactoe
    
    • g++ 是 C++ 编译器的命令。
    • main.cpp 是你的源文件。
    • -o tictactoe 指定编译生成的可执行文件名为 tictactoe (Windows 下会自动添加 .exe 后缀)。
  4. 运行你的游戏:

    ./tictactoe  # Linux/macOS
    tictactoe.exe # Windows
    
6.2 使用 IDE 编译和运行

如果你使用 Visual Studio、VS Code 或其他 IDE,通常可以直接点击“运行”或“构建并运行”按钮,IDE 会自动帮你完成编译和运行的步骤。

7. 运行效果示例

-----------------------------------欢迎来到井字棋!        
-------------------------------------- 井字棋 ---
-------------|   |  
---+---+---|   |  
---+---+---|   |  
-------------
玩家 X 的回合。请输入你的选择 (1-9): 5--- 井字棋 ---
-------------|   |  
---+---+---| X |  
---+---+---|   |  
-------------
玩家 O 的回合。请输入你的选择 (1-9): 1--- 井字棋 ---
-------------O |   |  
---+---+---| X |  
---+---+---|   |  
-------------
玩家 X 的回合。请输入你的选择 (1-9): 9--- 井字棋 ---
-------------O |   |  
---+---+---| X |  
---+---+---|   | X
-------------
玩家 O 的回合。请输入你的选择 (1-9): 2--- 井字棋 ---
-------------O | O |  
---+---+---| X |  
---+---+---|   | X
-------------
玩家 X 的回合。请输入你的选择 (1-9): 8--- 井字棋 ---
-------------O | O |  
---+---+---| X |  
---+---+---| X | X
-------------
玩家 O 的回合。请输入你的选择 (1-9): 3--- 井字棋 ---
-------------O | O | O
---+---+---| X |  
---+---+---| X | X
-------------
恭喜玩家 O 获胜!
游戏结束!感谢游玩!

8. 知识点回顾与进阶

通过这个井字棋项目,我们学习并实践了以下 C++ 核心概念:

  • std::vector 使用 vector<vector<char>> 来表示二维棋盘,这是 C++ 中处理动态数组和多维数据的重要方式。
  • 函数(Function): 将程序拆分成 displayBoardplayerMovecheckWincheckDraw 等独立函数,提高了代码的模块化、可读性和可维护性。
  • 函数参数传递:
    • 值传递: 默认方式,传递参数的副本。
    • 引用传递 (&): 允许函数修改外部变量(如 playerMove 修改 board),避免不必要的拷贝。
    • 常量引用 (const &): 允许函数高效地读取外部变量,但不允许修改(如 checkWincheckDraw 读取 board),兼顾效率和安全性。
  • bool 类型与逻辑判断: checkWincheckDraw 函数返回 bool 值,用于控制游戏流程。
  • 健壮的输入处理: 使用 cin.fail()cin.clear()cin.ignore() 来处理非数字输入和输入缓冲区问题,使程序更稳定。
  • 三元运算符 (? :): 简洁地实现玩家切换 currentPlayer = (currentPlayer == 'X') ? 'O' : 'X';

进阶挑战:自己尝试完成

  1. 重置游戏: 在游戏结束后,询问玩家是否“再玩一次”,如果选择是,则重置棋盘和玩家状态。
  2. 人机对战 (AI): 实现一个简单的电脑玩家。
    • 初级 AI: 随机选择一个空位落子。
    • 中级 AI: 优先选择能赢的位置,其次选择能阻止对手赢的位置。
  3. 统计分数: 记录玩家 X 和玩家 O 的胜场次数。
  4. 优化棋盘显示: 可以考虑用数字 1-9 来表示每个格子,方便玩家输入。
  5. 结构体/类封装: 将棋盘、当前玩家、游戏状态等数据封装到一个 Game 结构体或类中,进一步提升代码的面向对象特性。

9. 总结:C++ 进阶的里程碑!

恭喜你!你已经成功完成了你的第一个 C++ 进阶小游戏项目——井字棋!这标志着你对 C++ 的理解又深入了一步。

通过这个项目,你不仅掌握了 std::vector、函数的运用、引用传递等重要概念,更重要的是,你学会了如何将一个相对复杂的程序拆解成更小、更易于管理的部分,这是软件开发中非常重要的能力。

C++ 的学习是一个循序渐进的过程。多动手,多思考,多尝试,你就能不断突破,驾驭这门强大的语言,创造出更多精彩的作品!


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/96349.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/96349.shtml
英文地址,请注明出处:http://en.pswp.cn/diannao/96349.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

透射TEM 新手入门:快速掌握核心技能

目录 简介​ 一、TEM 基本知识 1. 核心原理&#xff08;理解图像本质&#xff09;​ 2. 关键结构与成像模式&#xff08;对应图像类型&#xff09;​ 二、TEM 数据处理 1. 预处理&#xff08;通用步骤&#xff09;​ 2. 衍射花样&#xff08;SAED&#xff09;处理&#x…

day075-MySQL数据库服务安装部署与基础服务管理命令

文章目录0. 老男孩思想-老男孩名言警句1. 数据库服务安装部署1.1 下载安装包1.2 系统环境准备1.2.1 关闭防火墙1.2.2 关闭selinux1.2.3 安装依赖软件1.2.4 卸载冲突软件1.3 安装程序1.3.1 上传软件包1.3.2 配置环境变量1.3.3 创建数据库存储数据目录1.3.4 创建数据库程序管理用…

Qt二维码生成器项目开发教程 - 从零开始构建专业级QR码生成工具

Qt二维码生成器项目开发教程 - 从零开始构建专业级QR码生成工具 项目概述 本项目是一个基于Qt框架开发的专业级二维码生成器&#xff0c;集成了开源的qrencode库&#xff0c;提供完整的QR码生成、预览、保存和分享功能。项目采用C语言开发&#xff0c;使用Qt的信号槽机制实现…

LLaVA-3D,Video-3D LLM,VG-LLM,SPAR论文解读

目录 一、LLaVA-3D 1、概述 2、方法 3、训练过程 4、实验 二、Video-3D LLM 1、概述 2、方法 3、训练过程 4、实验 三、SPAR 1、概述 2、方法 4、实验 四、VG-LLM 1、概述 2、方法 3、方法 4、实验 一、LLaVA-3D 1、概述 空间关系不足&#xff1a;传…

Spring两个核心IoCDI(二)

DI&#xff08;依赖注入&#xff09;就是从IoC容器中获取对象并赋值给某个属性&#xff0c;这就是依赖注入的过程。 关于依赖注入有3种方式&#xff1a; 1、属性注入 2、构造方法注入 3、setter注入 目录 1、属性注入 2、 构造方法注入 3、Setter方法注入 4、3种注入方式优…

广东省省考备考(第八十三天8.21)——言语、判断推理(强化训练)

言语理解与表达 错题解析 文段开篇介绍足够的执法权限对于基层治理高效运行的重要性&#xff0c;接着从两方面进行论证&#xff0c;介绍权限不足和权限过度下放对基层治理的负面影响&#xff0c;最后通过“因此”进行总结&#xff0c;强调一方面要完善执法目录动态调整机制和制…

字符串与算法题详解:最长回文子串、IP 地址转换、字符串排序、蛇形矩阵与字符串加密

字符串与算法题详解&#xff1a;最长回文子串、IP 地址转换、字符串排序、蛇形矩阵与字符串加密 前言 在编程题训练中&#xff0c;字符串相关的题目非常常见。本文将结合几个典型的例题&#xff0c;详细解析它们的解题思路和实现方式&#xff0c;帮助初学者循序渐进地掌握常用技…

从协同设计到绿色制造:工业云渲染的价值闭环

在智能制造、建筑工程、能源电力、船舶海工等工业场景中&#xff0c;3D可视化已从传统的桌面端逐步向Web端迁移&#xff0c;Web 3D凭借其跨平台、轻量化、实时交互等特性&#xff0c;已成为企业构建数字孪生、实现远程协作、推动云端交付的重要工具。这场技术变革不仅改变了工业…

算法第五十一天:图论part02(第十一章)

1.岛屿数量 99. 岛屿数量 &#x1f31f; 思路总结 — DFS 版 1️⃣ 问题本质 给定一个二维矩阵 grid&#xff0c;1 表示陆地&#xff0c;0 表示水 统计岛屿数量&#xff0c;每个岛屿由上下左右相邻的陆地组成 本质是 在二维网格中找连通块 的问题。 2️⃣ 核心思路 遍历矩阵…

杰里708n tws api 简介

/** 通过搜索码搜索tws设备*/int tws_api_search_sibling_by_code();/**打开可发现, 可连接&#xff0c;可被手机和tws搜索到*/int tws_api_wait_pair_by_code(u16 code, const char *name, int timeout_ms);int tws_api_wait_pair_by_ble(u16 code, const char *name, int tim…

高调光比 LED 恒流驱动芯片方案详解AP5165B:36V/1A

AP5165B 是深圳市世微半导体有限公司推出的一款高性能、连续电流模式的降压型&#xff08;Buck&#xff09;LED 恒流驱动芯片。该芯片适用于输入电压高于 LED 电压的应用场景&#xff0c;可驱动单颗或多颗串联的 LED&#xff0c;输出电流最高可达 1A&#xff0c;广泛用于非隔离…

【从零构建企业级线程池管理系统:Python并发编程实战指南】

从零构建企业级线程池管理系统&#xff1a;Python并发编程实战指南 技术博客 | 深入探索Python并发编程、Web开发与现代软件架构设计的完整实践 &#x1f680; 项目背景 在当今高并发的互联网时代&#xff0c;线程池作为并发编程的核心组件&#xff0c;其管理和监控能力直接影…

飞牛系统总是死机,安装个工具查看一下日志

崩溃转储 (kernel crash dump)如果你怀疑是内核 panic&#xff0c;可以开启 kdump 或 kernel crash dump。 安装&#xff1a;sudo apt install kdump-tools # Debian/Ubuntu sudo systemctl enable kdump 下次死机时&#xff0c;系统会把内存 dump 到 /var/crash 里。sudo syst…

2025年AI Agent技术深度解析:原理、应用与未来趋势

一、引言随着人工智能技术的飞速发展&#xff0c;AI Agent&#xff08;智能体&#xff09;作为人工智能领域的重要分支&#xff0c;正逐渐成为推动各行业智能化转型的关键力量。AI Agent具备自主感知、决策和执行能力&#xff0c;能够在复杂环境中完成特定任务&#xff0c;为人…

linux内核 - 内存分配机制介绍

在linux内核中&#xff0c;下面这张图说明了系统中存在一个可以满足各种内存请求的分配机制。根据你需要内存的用途&#xff0c;你可以选择最接近你目标的分配方式。最底层、最基础的分配器是 页分配器&#xff08;page allocator&#xff09;&#xff0c;它以页为单位分配内存…

PyTorch生成式人工智能——ACGAN详解与实现

PyTorch生成式人工智能——ACGAN详解与实现0. 前言1. ACGAN 简介1.1 ACGAN 技术原理1.2 ACGAN 核心思想1.3 损失函数2. 模型训练流程3. 使用 PyTorch 构建 ACGAN3.1 数据处理3.2 模型构建3.3 模型训练3.4 模型测试相关链接0. 前言 在生成对抗网络 (Generative Adversarial Net…

Python + 淘宝 API 开发:自动化采集商品数据的完整流程​

在电商数据分析、竞品监控和市场调研等场景中&#xff0c;高效采集淘宝商品数据是关键环节。本文将详细介绍如何利用 Python 结合 API&#xff0c;构建一套自动化的商品数据采集系统&#xff0c;涵盖从 API 申请到数据存储的完整流程&#xff0c;并提供可直接运行的代码实现。​…

2025.8.21总结

工作一年多了&#xff0c;在这期间&#xff0c;确实也有不少压力&#xff0c;但每当工作有压力的时候&#xff0c;最后面都会解决。好像每次遇到解决不了的事情&#xff0c;都有同事给我兜底。这种压力&#xff0c;确实会加速一个人的成长。这种狼性文化&#xff0c;这种环境&a…

VS2022 - C#程序简单打包操作

文章目录VS2022 - C#程序简单打包操作概述笔记实验过程新建工程让依赖的运行时程序安装包在安装时运行(如果发现运行时不能每次都安装程序&#xff0c;就不要做这步)关于”运行时安装程序无法每次都安装成功“的应对知识点尝试打包旧工程bug修复从需求属性中&#xff0c;可以原…

在JAVA中如何给Main方法传参?

一、在IDEA中进行传参&#xff1a;先创建一个类&#xff1a;MainTestimport java.util.Arrays;public class MainTest {public static void main(String[] args) {System.out.println(args.length);System.out.println(Arrays.toString(args));} }1.IDEA ---> 在运行的按钮上…