当前位置: 首页 > news >正文

从0到1:C++ 开启游戏开发奇幻之旅(一)

目录

为什么选择 C++ 进行游戏开发

性能卓越

内存管理精细

跨平台兼容性强

搭建 C++ 游戏开发环境

集成开发环境(IDE)

Visual Studio

CLion

图形库

SDL(Simple DirectMedia Layer)

SFML(Simple and Fast Multimedia Library)

C++ 游戏开发基础知识

面向对象编程(OOP)

内存管理

C++ 标准库(STL)


为什么选择 C++ 进行游戏开发

在游戏开发的广袤领域中,编程语言的选择犹如基石,奠定着整个项目的成败与走向。C++ 凭借其卓越的特性,在众多编程语言中脱颖而出,成为游戏开发的中流砥柱,深受开发者们的青睐。

性能卓越

游戏,尤其是大型 3A 游戏,对性能有着近乎苛刻的要求。每一次画面的渲染、每一个物理效果的模拟、每一次玩家操作的响应,都需要在极短的时间内完成,以确保游戏的流畅运行和玩家的沉浸体验。C++ 在性能方面的表现堪称惊艳。它允许开发者直接对内存进行操作,这意味着可以精准地控制数据的存储和读取位置,大大提高了数据的访问速度。在处理大量的图形数据、物理模拟数据以及音频数据时,这种直接内存操作的能力显得尤为关键。例如,在渲染一个复杂的 3D 游戏场景时,C++ 能够快速地将顶点数据、纹理数据等传递给图形处理器(GPU),从而实现高效的图形渲染,使得游戏画面更加细腻、逼真,帧率更加稳定。

不仅如此,C++ 的代码经过编译后,会直接转化为机器码,运行时无需解释器或虚拟机的介入,这使得它的执行速度大幅提升。与一些需要在虚拟机环境中运行的编程语言相比,C++ 能够更充分地利用计算机硬件的性能,减少了额外的性能开销。这种高效的执行速度,让游戏能够以更高的帧率运行,为玩家带来更加流畅、丝滑的游戏体验。在激烈的游戏对战中,每一帧的流畅都可能影响着玩家的操作和决策,C++ 的高性能无疑为游戏的竞技性和娱乐性提供了坚实的保障。

内存管理精细

内存管理是游戏开发中至关重要的一环。游戏在运行过程中,需要动态地分配和释放大量的内存,以存储各种游戏资源,如角色模型、场景地图、纹理贴图等。如果内存管理不善,就会导致内存泄漏、内存碎片化等问题,进而影响游戏的性能和稳定性,甚至可能导致游戏崩溃。C++ 赋予了开发者手动管理内存的能力,通过 new 和 delete 操作符(或者 malloc 和 free 函数),开发者可以精确地控制内存的分配和释放时机。这对于游戏开发来说意义重大。在创建和销毁游戏对象(如角色、道具等)时,能够准确地分配和回收内存,避免了内存的浪费和泄漏。在一个大型的多人在线游戏中,同时存在着大量的玩家角色和游戏道具,精细的内存管理可以确保游戏在长时间运行过程中,内存的使用始终保持在合理的范围内,保证游戏的稳定运行。

此外,C++ 还提供了智能指针(如 std::shared_ptr、std::unique_ptr 等)等工具,帮助开发者更方便地管理内存,减少手动管理内存带来的错误风险。智能指针能够自动跟踪对象的引用计数,当对象不再被使用时,自动释放其所占用的内存,有效地避免了内存泄漏的问题。在处理复杂的游戏对象层次结构和资源管理时,智能指针的使用可以大大简化代码,提高代码的可读性和可维护性。

跨平台兼容性强

在当今多元化的游戏市场中,跨平台开发已成为游戏开发者们必须面对的需求。玩家们使用着各种各样的设备和操作系统来玩游戏,包括 Windows、MacOS、Linux 等桌面操作系统,以及 iOS、Android 等移动操作系统,还有各种游戏主机。C++ 作为一种跨平台的编程语言,能够在多个操作系统和硬件平台上编译和运行。这意味着开发者可以使用相同的代码库,针对不同的平台进行简单的适配和优化,就能够创建出多个版本的游戏,大大减少了开发和维护的工作量。

许多流行的游戏引擎,如 Unreal Engine、Unity(底层部分也有 C++ 支持)、Cocos2d - x 等,都是基于 C++ 构建的。这些引擎提供了强大的跨平台支持,开发者可以借助这些引擎,轻松地将游戏移植到不同的平台上,实现一次开发,多平台发布。以 Unreal Engine 为例,它使用 C++ 作为核心编程语言,通过其提供的一系列工具和接口,开发者可以方便地将游戏部署到 PC、游戏机、移动设备等多种平台上,并且能够充分利用各个平台的硬件特性,为玩家提供一致的游戏体验。这种跨平台的能力,不仅扩大了游戏的受众范围,还提高了游戏的商业价值。

搭建 C++ 游戏开发环境

“工欲善其事,必先利其器”,搭建一个高效的开发环境是 C++ 游戏开发的首要任务。一个好的开发环境能够极大地提高开发效率,减少开发过程中的错误和麻烦。下面我们将详细介绍常用的开发工具和库,以及它们的安装和配置步骤。

集成开发环境(IDE)

Visual Studio

Visual Studio 是一款由微软开发的功能强大的集成开发环境,广泛应用于 Windows 平台下的 C++ 开发。它提供了丰富的功能,包括代码编辑、调试、智能感知、代码分析等,能够帮助开发者高效地编写和调试代码。

安装步骤如下:

  1. 进入 Visual Studio 官网 (https://visualstudio.microsoft.com/),选择下载 Windows 版,并选择 Community 2019 社区版本(社区版对于个人开发者和小型团队是免费的,功能也非常齐全,足以满足大多数游戏开发的需求)进行下载,保存软件到电脑中。
  1. 双击运行下载的安装文件,弹出安装界面,选择 “使用 C++ 的桌面开发” 这一选项,如需其他,自行勾选。点击安装按钮开始安装。安装时间会依据网速、电脑设备等因素而有所不同,在此期间可以稍作等待,或者做一些其他的事情。
  1. 安装成功后提示重启,点击重启完成剩余配置。
  1. 在开始菜单找到 Visual Studio 2019 并且点击运行,弹出初始界面,点击 “创建新项目” 按钮 ,如果出现 C++ 项目模板选项,证明安装成功,并可以创建 C++ 项目。
CLion

CLion 是一款由 JetBrains 开发的跨平台 C++ 集成开发环境,它以其智能的代码编辑、强大的调试功能和对多种构建系统的支持而受到开发者的喜爱。无论是在 Windows、MacOS 还是 Linux 系统上,CLion 都能提供一致的高效开发体验。

安装步骤如下:

  1. 首先,从 CLion 官网 (https://www.jetbrains.com/clion/download/) 下载 Clion 安装文件。
  1. 下载完成后,解压缩安装文件,并运行 clion.exe 文件(在 Windows 系统下)。
  1. 进入 Clion 的安装界面,可以选择自定义安装选项或者选择默认选项,然后点击 “Next” 按钮。
  1. 勾选用户协议并继续。
  1. 在安装选项中,可以选择安装路径、添加图标等信息,然后点击 “Install” 按钮。
  1. 安装完成后,进行一些配置才能使用 Clion。在 Clion 主界面中,点击 “File” 菜单,然后选择 “Settings” 选项;找到 “Build, Execution, Deployment” 选项,并选择 “CMake” 选项;在 “CMake” 选项中,设置 CMake 和编译器的路径,以及其他相关选项;设置完成后,点击 “Apply” 按钮保存更改;最后,在 Clion 中创建一个新项目,并将代码添加到项目中。

图形库

SDL(Simple DirectMedia Layer)

SDL 是一个跨平台的多媒体库,它提供了对音频、键盘、鼠标、游戏杆和图形硬件的低级访问,非常适合用于开发 2D 游戏和多媒体应用程序。SDL 的设计目标是简单易用,同时又具有足够的灵活性和强大的功能,能够满足不同类型游戏的开发需求。

安装步骤如下(以 Windows 系统为例):

  1. 从 SDL 官网 (https://www.libsdl.org/download-2.0.php) 下载对应操作系统版本的 SDL2 库。
  1. 解压文件,将下载的压缩包解压至任意位置,得到类似如下的目录结构:
SDL2-2.26.1/
├── include/
│   └── SDL2/
├── lib/
│   ├── x86/
│   │   ├── SDL2.dll
│   │   ├── SDL2main.lib
│   │   └── SDL2.lib
│   └── x64/
│       ├── SDL2.dll
│       ├── SDL2main.lib
│       └── SDL2.lib
└── share/└── doc/└── SDL2/
  1. 配置开发环境(以 Visual Studio 为例):打开 Visual Studio,创建一个新的 C++ 项目,在项目中右键单击 “项目名称”,选择 “属性”;在左侧选择 “C/C++” -> “常规”,在 “附加包含目录” 中添加 SDL2-2.26.1/include 目录;在左侧选择 “链接器” -> “常规”,在 “附加库目录” 中添加 SDL2-2.26.1/lib/x64(如果是 x86 项目,则选择 x86 目录)目录;在左侧选择 “链接器” -> “输入”,在 “附加依赖项” 中添加 SDL2.lib 和 SDL2main.lib;将 SDL2-2.26.1/lib/x64(或 x86)目录下的 SDL2.dll 文件复制到项目的输出目录(通常是 Debug 或 Release 文件夹)。
SFML(Simple and Fast Multimedia Library)

SFML 也是一个跨平台的 C++ 多媒体库,它提供了简单直观的 API,用于处理图形、音频、网络和窗口等功能。SFML 的优势在于其简洁易用的接口和丰富的文档,对于初学者来说是一个很好的选择,能够快速上手并开发出有趣的 2D 游戏。

安装步骤如下(以 Windows 系统为例):

  1. 从 SFML 官网 (https://www.sfml-dev.org/download/sfml/2.6.0/) 下载适用于 Visual Studio 的 SFML 库。
  1. 解压文件,将下载的压缩包解压至任意位置,得到类似如下的目录结构:
SFML-2.6.0/
├── include/
│   └── SFML/
├── lib/
│   ├── libsfml-graphics-d.lib
│   ├── libsfml-window-d.lib
│   ├── libsfml-system-d.lib
│   ├── libsfml-audio-d.lib
│   ├── libsfml-network-d.lib
│   ├── libsfml-graphics.lib
│   ├── libsfml-window.lib
│   ├── libsfml-system.lib
│   ├── libsfml-audio.lib
│   └── libsfml-network.lib
└── share/└── sfml/├── cmake/└──...
  1. 配置开发环境(以 Visual Studio 为例):打开 Visual Studio,创建一个新的 C++ 项目,在项目中右键单击 “头文件”,选择 “添加现有项”,并选择 SFML-2.6.0/include 目录下的所有.hpp 文件,以添加 SFML 的头文件;在同样的位置右键单击 “源文件”,选择 “添加现有项”,并选择 SFML-2.6.0/lib 目录下与编译器相匹配的所有库文件(.lib 或.a)。例如,如果使用的是 64 位的编译器,就应该添加 SFML-2.6.0/lib/x64 下的所有库文件;在项目中右键单击,选择 “属性” 窗口。在左侧选择 “C/C++” -> “常规”,在 “附加包含目录” 中添加 SFML-2.6.0/include 目录;在左侧选择 “链接器” -> “常规”,在 “附加库目录” 中添加 SFML-2.6.0/lib 目录;在左侧选择 “链接器” -> “输入”,在 “附加依赖项” 中添加以下库文件(根据需要添加即可):sfml-graphics.lib、sfml-window.lib、sfml-system.lib、sfml-audio.lib、opengl32.lib、freetype.lib、winmm.lib、gdi32.lib ;如果使用的是静态库,应该添加 SFML_STATIC 编译器预处理器定义;将 SFML-2.6.0/bin 目录下的所有.dll 文件复制到项目的输出目录(通常是 Debug 或 Release 文件夹)。

C++ 游戏开发基础知识

在 C++ 游戏开发的旅程中,掌握一些基础知识是开启成功之门的关键。这些知识构成了游戏开发的基石,无论是小型的休闲游戏,还是大型的 3A 游戏,都离不开它们的支撑。下面,让我们深入探讨面向对象编程、内存管理以及 C++ 标准库在游戏开发中的重要性和应用。

面向对象编程(OOP)

面向对象编程(OOP)是 C++ 的核心特性之一,它为游戏开发带来了极大的便利和灵活性。OOP 主要包含封装、继承、多态这几个概念。

封装,就像是给游戏中的各种元素加上了一个 “保护壳”。在游戏中,每个角色都有自己的生命值、攻击力、防御力等属性,以及移动、攻击、防御等行为。通过封装,我们可以将这些属性和行为组合在一起,形成一个类。以《英雄联盟》为例,英雄 “艾克” 就是一个类的实例,他的生命值、攻击力等属性被封装在这个类中,而他的技能 “时间卷曲器”“相位俯冲” 等行为也通过类的成员函数来实现。外部代码不能直接访问这些属性,只能通过类提供的公共方法来操作,这就保证了数据的安全性和一致性。比如,其他玩家不能直接修改 “艾克” 的生命值,只能通过攻击等合法的游戏行为来影响他的生命值,这样就避免了数据被随意篡改,保证了游戏的公平性和稳定性。

继承,则是实现代码复用的重要手段。在游戏中,有很多相似的对象,比如不同类型的怪物,它们可能都有一些共同的属性和行为,如生命值、攻击力、移动等。我们可以创建一个基类,包含这些共同的属性和行为,然后让不同类型的怪物类继承这个基类。以《暗黑破坏神》系列游戏为例,游戏中有各种恶魔和怪物,它们都继承自一个 “怪物” 基类。“沉沦魔” 类继承自 “怪物” 基类,它不仅拥有 “怪物” 基类的基本属性和行为,还可以有自己特有的属性和行为,比如更灵活的移动方式、特殊的攻击技能等。通过继承,我们可以减少代码的重复编写,提高开发效率。当我们需要修改怪物的一些基本属性时,只需要在基类中进行修改,所有继承自这个基类的怪物类都会自动继承这些修改,大大方便了代码的维护和扩展。

多态,是指同一个操作作用于不同的对象,可以产生不同的结果。在游戏中,多态的应用非常广泛。以《鬼泣》系列游戏为例,游戏中的角色 “但丁” 可以使用不同的武器,如大剑、双枪等。每个武器都有自己的攻击方式和效果,但是我们可以通过一个统一的接口来调用这些武器的攻击方法。当 “但丁” 使用大剑时,调用的是大剑的攻击方法,产生大剑的攻击效果;当他使用双枪时,调用的是双枪的攻击方法,产生双枪的攻击效果。这就是多态的体现,它使得代码更加灵活和可扩展。当我们需要添加新的武器时,只需要创建一个新的武器类,实现统一的攻击接口,就可以轻松地将新武器融入游戏中,而不需要大量修改现有的代码。

内存管理

在 C++ 游戏开发中,内存管理是一个至关重要的环节,它直接影响着游戏的性能和稳定性。C++ 提供了两种主要的内存分配方式:堆栈内存和堆内存,它们各有特点和适用场景。

栈内存是一种自动分配和释放的内存区域,它的分配和释放速度非常快,就像在一个栈中放入和取出物品一样简单高效。函数的局部变量和函数调用信息通常存储在栈上。当函数被调用时,局部变量会在栈上自动分配内存空间;当函数执行结束时,这些局部变量所占用的内存会自动被释放。在一个简单的游戏函数中,比如计算角色移动距离的函数:

void calculateMoveDistance() {int speed = 5; // 局部变量speed存储在栈上int time = 10; // 局部变量time存储在栈上int distance = speed * time; // 局部变量distance存储在栈上// 函数执行结束,speed、time、distance所占用的栈内存自动释放
}

栈内存的优点是速度快、效率高,但是它的大小是有限的,并且变量的生命周期与函数的作用域紧密相关。如果在栈上分配过多的内存,或者在函数中创建了大型的局部数组,可能会导致栈溢出,从而使程序崩溃。

堆内存则是用于动态分配内存的区域,它由程序员手动控制内存的分配和释放。在游戏中,当我们需要创建一些动态的对象,如角色、道具等,并且这些对象的生命周期需要根据游戏的运行情况来动态管理时,就需要使用堆内存。以创建一个游戏角色为例:

class Character {
public:int health;int attackPower;// 其他属性和方法
};int main() {Character* character = new Character(); // 在堆上分配内存创建Character对象character->health = 100;character->attackPower = 20;// 使用character对象delete character; // 手动释放堆内存,避免内存泄漏return 0;
}

堆内存的优点是可以根据需要动态分配内存大小,灵活性高,但是它的分配和释放过程相对复杂,需要程序员手动操作,并且速度比栈内存慢。如果在堆上分配了内存,但是在使用完毕后没有及时释放,就会导致内存泄漏,随着游戏的运行,内存占用会越来越高,最终可能导致游戏卡顿甚至崩溃。

为了更好地管理堆内存,C++11 引入了智能指针(如std::shared_ptr、std::unique_ptr等)。智能指针能够自动跟踪对象的引用计数,当对象不再被使用时,自动释放其所占用的内存,有效地避免了内存泄漏的问题。以std::shared_ptr为例:

#include <memory>
#include <iostream>class Character {
public:int health;int attackPower;Character() : health(100), attackPower(20) {}~Character() { std::cout << "Character destroyed" << std::endl; }
};int main() {std::shared_ptr<Character> character = std::make_shared<Character>();// 使用character对象// 当character离开作用域时,其引用计数降为0,自动释放所指向的Character对象的内存return 0;
}

在这个例子中,std::shared_ptr会自动管理Character对象的生命周期,当character离开作用域时,它所指向的Character对象的内存会被自动释放,无需手动调用delete。智能指针的使用大大简化了内存管理,提高了代码的安全性和可维护性。

C++ 标准库(STL)

C++ 标准库(STL)是 C++ 编程中的强大工具集,它提供了丰富的容器和算法,在游戏开发中有着广泛的应用,能够大大提高开发效率。

STL 中的容器是存储和管理数据的重要工具,其中vector、list、map是比较常用的容器。vector是一个动态数组,它允许在运行时动态地调整大小,并且支持快速的随机访问。在游戏中,vector常用于存储游戏对象的集合,如游戏中的角色列表、道具列表等。以一个简单的射击游戏为例,我们可以使用vector来存储所有的敌人:

#include <vector>
#include <iostream>class Enemy {
public:int health;int attackPower;Enemy() : health(50), attackPower(10) {}
};int main() {std::vector<Enemy> enemies;for (int i = 0; i < 10; i++) {enemies.push_back(Enemy());}// 访问和操作enemies中的敌人for (size_t i = 0; i < enemies.size(); i++) {std::cout << "Enemy " << i << " health: " << enemies[i].health << std::endl;}return 0;
}

在这个例子中,vector可以方便地添加和访问敌人对象,并且在需要时自动调整大小,非常适合存储动态变化的游戏对象集合。

list是一个双向链表,它的特点是在链表的任何位置进行插入和删除操作都非常高效,但是不支持随机访问。在游戏中,当需要频繁地插入和删除元素时,list就派上了用场。比如在一个实时策略游戏中,单位的创建和销毁非常频繁,我们可以使用list来存储游戏中的单位:

#include <list>
#include <iostream>class Unit {
public:int health;int attackPower;Unit() : health(100), attackPower(20) {}
};int main() {std::list<Unit> units;units.push_back(Unit()); // 在链表尾部插入一个单位units.push_front(Unit()); // 在链表头部插入一个单位auto it = units.begin();++it; // 移动到第二个单位units.insert(it, Unit()); // 在第二个单位之前插入一个单位// 删除单位it = units.begin();units.erase(it); // 删除第一个单位// 遍历listfor (const auto& unit : units) {std::cout << "Unit health: " << unit.health << std::endl;}return 0;
}

在这个例子中,list的高效插入和删除操作使得它非常适合处理游戏中频繁变化的单位集合。

map是一个关联容器,它存储的是键值对,并且会根据键自动排序。在游戏中,map常用于存储需要根据某个键来查找对应值的数据,如游戏中的道具字典,我们可以使用道具的 ID 作为键,道具的详细信息作为值:

#include <map>
#include <string>
#include <iostream>class Item {
public:std::string name;int value;Item(const std::string& n, int v) : name(n), value(v) {}
};int main() {std::map<int, Item> items;items[1] = Item("Health Potion", 50); // 添加一个ID为1的道具items[2] = Item("Mana Potion", 30); // 添加一个ID为2的道具// 根据ID查找道具auto it = items.find(1);if (it!= items.end()) {std::cout << "Item name: " << it->second.name << ", value: " << it->second.value << std::endl;}return 0;
}

在这个例子中,map可以快速地根据道具 ID 查找到对应的道具信息,非常方便管理和查找游戏中的各种数据。

STL 中的算法也是游戏开发中不可或缺的工具,其中sort和find是比较常用的算法。sort算法用于对容器中的元素进行排序,在游戏中,经常需要对游戏对象进行排序,如根据角色的等级对角色进行排序,或者根据玩家的得分对玩家进行排名。以对玩家得分进行排序为例:

#include <vector>
#include <algorithm>
#include <iostream>struct Player {std::string name;int score;Player(const std::string& n, int s) : name(n), score(s) {}
};// 自定义比较函数,用于按得分从高到低排序
bool compareByScore(const Player& p1, const Player& p2) {return p1.score > p2.score;
}int main() {std::vector<Player> players;players.push_back(Player("Alice", 80));players.push_back(Player("Bob", 90));players.push_back(Player("Charlie", 70));// 对玩家按得分进行排序std::sort(players.begin(), players.end(), compareByScore);// 输出排序后的玩家列表for (const auto& player : players) {std::cout << "Player: " << player.name << ", Score: " << player.score << std::endl;}return 0;
}

在这个例子中,std::sort算法可以方便地对玩家列表进行排序,使得玩家按照得分从高到低排列。

find算法用于在容器中查找指定的元素,在游戏中,经常需要查找某个特定的游戏对象,如查找某个 ID 对应的角色,或者查找某个位置的道具。以查找某个 ID 对应的角色为例:

#include <vector>
#include <algorithm>
#include <iostream>class Character {
public:int id;std::string name;Character(int i, const std::string& n) : id(i), name(n) {}
};int main() {std::vector<Character> characters;characters.push_back(Character(1, "Warrior"));characters.push_back(Character(2, "Mage"));characters.push_back(Character(3, "Rogue"));// 查找ID为2的角色auto it = std::find_if(characters.begin(), characters.end(), [](const Character& c) {return c.id == 2;});if (it!= characters.end()) {std::cout << "Found Character: " << it->name << std::endl;} else {std::cout << "Character not found" << std::endl;}return 0;
}

在这个例子中,std::find_if算法可以在characters容器中查找 ID 为 2 的角色,如果找到则输出角色的名字,否则输出提示信息。

相关文章:

从0到1:C++ 开启游戏开发奇幻之旅(一)

目录 为什么选择 C 进行游戏开发 性能卓越 内存管理精细 跨平台兼容性强 搭建 C 游戏开发环境 集成开发环境&#xff08;IDE&#xff09; Visual Studio CLion 图形库 SDL&#xff08;Simple DirectMedia Layer&#xff09; SFML&#xff08;Simple and Fast Multim…...

IGBT的损耗计算的学习【2025/1/24】

可以通过示波器实测IGBT电压电流波形&#xff0c;然后通过示波器的math功能将电压电流波形乘积后积分求损耗。 软开管&#xff1a;给了导通信号&#xff0c;但是电流并没有从此IGBT流过 IGBT&#xff08;绝缘栅双极晶体管&#xff09;的损耗主要分为 导通损耗 和 开关损耗 两部…...

Python从0到100(八十五):神经网络-使用迁移学习完成猫狗分类

前言: 零基础学Python:Python从0到100最新最全教程。 想做这件事情很久了,这次我更新了自己所写过的所有博客,汇集成了Python从0到100,共一百节课,帮助大家一个月时间里从零基础到学习Python基础语法、Python爬虫、Web开发、 计算机视觉、机器学习、神经网络以及人工智能…...

Oracle迁移DM数据库

Oracle迁移DM数据库 本文记录使用达梦官方数据迁移工具DTS&#xff0c;将Oracle数据库的数据迁移至达梦数据库。 1 数据准备 2 DTS工具操作步骤 2.1 创建工程 打开DTS迁移工具&#xff0c;点击新建工程&#xff0c;填写好工程信息&#xff0c;如图&#xff1a; 2.2 新建迁…...

通过 NAudio 控制电脑操作系统音量

根据您的需求&#xff0c;以下是通过 NAudio 获取和控制电脑操作系统音量的方法&#xff1a; 一、获取和控制系统音量 &#xff08;一&#xff09;获取系统音量和静音状态 您可以使用 NAudio.CoreAudioApi.MMDeviceEnumerator 来获取系统默认音频设备的音量和静音状态&#…...

AI刷题-最小化团建熟悉程度和

目录 问题描述 输入格式 输出格式 解题思路&#xff1a; 状态表示 状态转移 动态规划数组 预处理 实现&#xff1a; 1.初始化&#xff1a; 2.动态规划部分&#xff1a; &#xff08;1&#xff09;对于已分组状态的&#xff0c;跳过&#xff1a; &#xff08;2&…...

Day36:统计字符串个数

在 Python 中&#xff0c;字符串的统计功能是处理文本数据时非常重要的一部分。我们可以使用多种方法来统计字符串中的字符、子字符串、单词以及出现次数等。Python 提供了内建的方法和函数&#xff0c;如 count()、len() 和正则表达式&#xff0c;可以帮助我们高效地进行这些统…...

数字图像处理:实验六

uu们&#xff01;大家好&#xff0c;2025年的新年就要到来&#xff0c;咸鱼哥在这里祝大家在2025年每天开心快乐&#xff0c;天天挣大钱&#xff0c;自由自在&#xff0c;健健康康&#xff0c;万事如意&#xff01;&#xff08;要是咸鱼哥嘴笨的话&#xff0c;还望大家多多包涵…...

【2025年数学建模美赛C题】第1-5问F奖解题思路+高级绘图+可运行代码

基于多模型分析的奥运会奖牌预测与影响因素研究 解题思路一、问题重述二、问题分析三、模型假设与符号说明四、数据预处理五、奖牌榜预测5.1 基于LSTM长短期记忆循环神经网络的预测模型的建立5.2 模型预测结果 六、首枚奖牌预测6.1 BP神经网络的建立6.2 模型预测结果 七、各国奖…...

记一次STM32编译生成BIN文件过大的问题(基于STM32CubeIDE)

文章目录 问题描述解决方法更多拓展 问题描述 最近在一个项目中使用了 STM32H743 单片机&#xff08;基于 STM32CubeIDE GCC 开发&#xff09;&#xff0c;它的内存分为了 DTCMRAM RAM_D1 RAM_D2 …等很多部分。其中 DTCM 的速度是比通常的内存要快的&#xff0c;缺点是不支持…...

【设计模式-行为型】备忘录模式

一、什么是备忘录模式 来到备忘录模式了&#xff0c;这个模式我感觉相对简单一些&#xff0c;就是备份&#xff0c;或者快照。跟前面一样为了加深理解&#xff0c;我们引入一个电影情结来说明啥是备忘录模式&#xff0c;以来加深大家对备忘录模式的认识。那么&#xff0c;在电影…...

使用Cline+deepseek实现VsCode自动化编程

不知道大家有没有听说过cursor这个工具&#xff0c;类似于AIVsCode的结合体&#xff0c;只要绑定chatgpt、claude等大模型API&#xff0c;就可以实现对话式自助编程&#xff0c;简单闲聊几句便可开发一个软件应用。 但cursor受限于外网&#xff0c;国内用户玩不了&#xff0c;…...

React 前端框架实战教程

&#x1f4dd;个人主页&#x1f339;&#xff1a;一ge科研小菜鸡-CSDN博客 &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; 引言 React 是由 Facebook 开发的前端 JavaScript 库&#xff0c;旨在构建高效、灵活的用户界面&#xff0c;尤其适用于单页应用…...

输入带空格的字符串,求单词个数

输入带空格的字符串&#xff0c;求单词个数 __ueooe_eui_sjje__ ---->3syue__jdjd____die_ ---->3shuue__dju__kk ---->3 #include <stdio.h> #include <string.h>// 自定义函数来判断字符是否为空白字符 int isSpace(char c) {return c || c \t || …...

Kafka 日志存储 — 日志清理

Kafka 提供两种日志清理策略&#xff1a;日志清理(Log Delete)与日志压缩(Log Compaction)。 1 日志清理 通过broker端参数log.cleanup.policy来设置日志清理策略&#xff0c;默认值为“delete”。如果要采用日志压缩的清理策略&#xff0c;则设置为“compact”。可以同时支持…...

51单片机入门_02_C语言基础0102

C语言基础部分可以参考我之前写的专栏C语言基础入门48篇 以及《从入门到就业C全栈班》中的C语言部分&#xff0c;本篇将会结合51单片机讲差异部分。 课程主要按照以下目录进行介绍。 文章目录 1. 进制转换2. C语言简介3. C语言中基本数据类型4. 标识符与关键字5. 变量与常量6.…...

从零开始学 HTML:构建网页的基本框架与技巧

系列文章目录 01-从零开始学 HTML&#xff1a;构建网页的基本框架与技巧 文章目录 系列文章目录前言一、HTML 文档的基本框架1.1 <!DOCTYPE html>、<html>、<head>、<body> 标签解析1.1.1 <!DOCTYPE html> 标签1.1.2 <html> 标签1.1.3 &l…...

vim的特殊模式-可视化模式

可视化模式&#xff1a;按 v进入可视化模式 选中 y复制 d剪切/删除 可视化块模式: ctrlv 选中 y复制 d剪切/删除 示例&#xff1a; &#xff08;vim可视化模式的进阶使用&#xff1a;vim可视化模式的进阶操作-CSDN博客&#xff09;...

LeetCode - Google 大模型校招10题 第1天 Attention 汇总 (3题)

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/145368666 GroupQueryAttention(分组查询注意力机制) 和 KVCache(键值缓存) 是大语言模型中的常见架构&#xff0c;GroupQueryAttention 是注意力…...

【ES实战】治理项之索引模板相关治理

索引模板治理 文章目录 索引模板治理问题现象分析思路操作步骤问题程序化方案索引与索引模板增加分片数校验管理 彩蛋如何查询Flink on Yarn 模式下的Task Manager日志相关配置查询已停止的Flink任务查询未停止的Flink任务 问题现象 在集群索引新建时&#xff0c;索引的分片比…...

Ansible自动化运维实战--script、unarchive和shell模块(6/8)

文章目录 一、script模块1.1、功能1.2、常用参数1.3、举例 二、unarchive模块2.1、功能2.2、常用参数2.3、举例 三、shell模块3.1、功能3.2、常用参数3.3、举例 一、script模块 1.1、功能 Ansible 的 script 模块允许你在远程主机上运行本地的脚本文件&#xff0c;其提供了一…...

完全平方数——唯一分解定理

文章目录 一、唯一分解定理是什么&#xff1f;1.定义2.示例3.代码模板 二、例题1>问题描述&#xff08;2021蓝桥杯省赛&#xff09;输入格式输出格式样例输入 1样例输出 1样例输入 2样例输出 2评测用例规模与约定 2>解题思路3>假娃3>C嘎嘎 一、唯一分解定理是什么&…...

可见光通信代码仿真

可见光通信代码仿真。可以在matlab上进行matlab仿真。 资源文件列表 visible_light/catch.m , 119 visible_light/HLOS.m , 283 visible_light/PRXLOS.m , 129 visible_light/RO.m , 155 visible_light/untitled.fig , 134740 visible_light/visible_light_comms.m , 1620 vis…...

Sklearn 中的逻辑回归

逻辑回归的数学模型 基本模型 逻辑回归主要用于处理二分类问题。二分类问题对于模型的输出包含 0 和 1&#xff0c;是一个不连续的值。分类问题的结果一般不能由线性函数求出。这里就需要一个特别的函数来求解&#xff0c;这里引入一个新的函数 Sigmoid 函数&#xff0c;也成…...

spark运行流程

spark运行流程 任务提交后&#xff0c;先启动 Driver 程序随后 Driver 向集群管理器注册应用程序集群管理器根据此任务的配置文件分配 Executor 并启动Driver 开始执行 main 函数&#xff0c;Spark 查询为懒执行&#xff0c;当执行到 Action 算子时开始反向推 算&#xff0c;根…...

MapReduce,Yarn,Spark理解与执行流程

MapReduce的API理解 Mapper 如果是单词计数&#xff1a;hello&#xff1a;1&#xff0c; hello&#xff1a;1&#xff0c; world&#xff1a;1 public void map(Object key, // 首字符偏移量Text value, // 文件的一行内容Context context) // Mapper端的上下文&#xff0c;…...

elk 安装

创建elk网络 docker network create -d bridge elkelasticsearch 创建目录 mkdir -p /data/elasticsearch/{conf,logs,data,plugins}vim /data/elasticsearch/conf/elasticsearch.ymlcluster.name: "es-cluster" network.host: 0.0.0.0 xpack.security.enabled: tr…...

二十三种设计模式-桥接模式

桥接模式&#xff08;Bridge Pattern&#xff09;是一种结构型设计模式&#xff0c;其核心思想是将抽象与实现解耦&#xff0c;让它们可以独立变化。桥接模式主要用于解决类的继承问题&#xff0c;避免由于继承而带来的类层次结构过于复杂和难以维护的问题。 1. 核心概念 桥接…...

【Validator】字段验证器struct与多层级验证,go案例

标签用法总结表 标签功能代码实例required字段必填Name string \v:“required”alphaunicode验证字段是否只包含字母和 Unicode 字符Name string \v:“alphaunicode”gte验证字段值是否大于等于指定值Age uint8 \v:“gte10”lte验证字段值是否小于等于指定值Age uint8 \v:“lt…...

第19篇:python高级编程进阶:使用Flask进行Web开发

第19篇&#xff1a;python高级编程进阶&#xff1a;使用Flask进行Web开发 内容简介 在第18篇文章中&#xff0c;我们介绍了Web开发的基础知识&#xff0c;并使用Flask框架构建了一个简单的Web应用。本篇文章将深入探讨Flask的高级功能&#xff0c;涵盖模板引擎&#xff08;Ji…...

jEasyUI 创建复杂布局

jEasyUI 创建复杂布局 引言 jEasyUI 是一款基于 jQuery 的开源 UI 框架,它提供了一套丰富的 UI 组件,帮助开发者快速构建美观、易用的 Web 应用。在开发过程中,复杂布局的创建往往是一个挑战。本文将详细介绍如何使用 jEasyUI 创建复杂布局,帮助开发者提升工作效率。 前…...

前端【8】HTML+CSS+javascript实战项目----实现一个简单的待办事项列表 (To-Do List)

目录 一、功能需求 二、 HTML 三、CSS 四、js 1、绑定事件与初始设置 2.、绑定事项 &#xff08;1&#xff09;添加操作&#xff1a; &#xff08;2&#xff09;完成操作 &#xff08;3&#xff09;删除操作 &#xff08;4&#xff09;修改操作 3、完整js代码 总结…...

java爬虫工具Jsoup学习

目录 前言 一、基本使用 二、爬取豆瓣电影的案例 三、Jsoup能做什么&#xff1f; 四、Jsoup相关概念 五、Jsoup获取文档 六、定位选择元素 七、获取数据 八、具体案例 前言 JSoup是一个用于处理HTML的Java库&#xff0c;它提供了一个非常方便类似于使用DOM&#xff0…...

RabbitMQ模块新增消息转换器

文章目录 1.目录结构2.代码1.pom.xml 排除logging2.RabbitMQConfig.java3.RabbitMQAutoConfiguration.java 1.目录结构 2.代码 1.pom.xml 排除logging <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/PO…...

大话特征工程:1.维数灾难与特征轮回

一、维度深渊 公元 2147 年&#xff0c;人类文明进入了数据驱动的超级智能时代。从金融到医疗&#xff0c;从教育到娱乐&#xff0c;所有决策都仰赖“全维计算网络”&#xff08;高维特征空间&#xff09;。这套系统将全球所有信息抽象成数以亿计的多维特征&#xff08…...

学院失物招领 app 的设计与实现

标题:学院失物招领 app 的设计与实现 内容:1.摘要 随着移动互联网的普及和智能手机的广泛应用&#xff0c;越来越多的人开始使用手机应用程序来解决生活中的各种问题。在大学校园中&#xff0c;失物招领是一个常见的问题&#xff0c;每年都有大量的学生丢失或捡到物品。为了解…...

std::function的简易实现

本节我们来实现一个简易的std::function 我们知道std::function是用来包装可调用对象的&#xff0c;在C中&#xff0c;可调用对象包括 普通函数、lambda表达式、重载了()操作符的类对象、类静态函数、类成员函数这几类。 C程序的编译顺序&#xff1a;预处理(xxx.i) 编译(xxx.…...

笔试-二维数组1

应用 快递业务有N个站点&#xff0c;1<N<10000&#xff1b;站点0、站点1可达&#xff0c;记作0-1&#xff1b;如果0-1、1-2&#xff0c;则站点0、站点2可达&#xff0c;记作0-2&#xff1b;s[i][j]1表示i-j可达&#xff0c;反之s[i][j]0表示i-j不可达&#xff1b;s[i][j…...

【Pytest】生成html报告中,中文乱码问题解决方案

import pytestif __name__ "__main__":# 只运行 tests 目录下的测试用例&#xff0c;并生成 HTML 报告pytest.main([-v, -s, --htmlreport.html, tests])可以以上方式生成&#xff0c;也可以在pytest.ini中设置 [pytest] addopts --htmlreport.html --self-contai…...

汽车网络信息安全-ISO/SAE 21434解析(下)

目录 第十二~十四章 - 后开发阶段 1. 十二章节 - 生产 2. 十三章节 - 运营与维护 网络安全事件响应 更新 3. 十四章节 - 结束网络安全支持和停用 结束网络安全支持 报废 第十五章 - TARA分析方法 1. 概述 2. 资产识别 3. 威胁场景识别 4. 影响评级 5. 攻击路径分…...

局域网中 Windows 与 Mac 互相远程连接的最佳方案

由于工作需要&#xff0c;经常需要远程连接或登录到几台不同的工作用机上进行操作。 下面基于免费、高体验等基本诉求&#xff0c;简要记录几种不同场景下的实践方案选择&#xff0c;仅供参考。如您有更简单且更优的方案&#xff0c;欢迎一起探讨。 1 远程桌面连接的几种不同…...

Qt调用ffmpeg库录屏并进行UDP组播推流

基于以下参考链接&#xff0c;采用其界面和程序框架&#xff0c;实现实时推送UDP组播视频流&#xff0c;替换原拉流功能 https://blog.csdn.net/u012532263/article/details/102736700 源码在windows&#xff08;qt-opensource-windows-x86-5.12.9.exe&#xff09;、ubuntu20.…...

机器学习 - 初学者需要弄懂的一些线性代数的概念

一、单位矩阵 在数学中&#xff0c;单位矩阵是一个方阵&#xff0c;其主对角线上的元素全为1&#xff0c;其余元素全为0。单位矩阵在矩阵乘法中起到类似于数字1在数值乘法中的作用&#xff0c;即任何矩阵与单位矩阵相乘&#xff0c;结果仍为原矩阵本身。 单位矩阵的定义&…...

vscode无法格式化go代码的问题

CTRLshiftp 点击Go:Install/Update Tools 点击全选&#xff0c;OK&#xff01;...

实验二 数据库的附加/分离、导入/导出与备份/还原

实验二 数据库的附加/分离、导入/导出与备份/还原 一、实验目的 1、理解备份的基本概念&#xff0c;掌握各种备份数据库的方法。 2、掌握如何从备份中还原数据库。 3、掌握数据库中各种数据的导入/导出。 4、掌握数据库的附加与分离&#xff0c;理解数据库的附加与分离的作用。…...

基于Django的个人博客系统的设计与实现

【Django】基于Django的个人博客系统的设计与实现&#xff08;完整系统源码开发笔记详细部署教程&#xff09;✅ 目录 一、项目简介二、项目界面展示三、项目视频展示 一、项目简介 系统采用Python作为主要开发语言&#xff0c;结合Django框架构建后端逻辑&#xff0c;并运用J…...

PostgreSQL TRUNCATE TABLE 操作详解

PostgreSQL TRUNCATE TABLE 操作详解 引言 在数据库管理中,经常需要对表进行操作以保持数据的有效性和一致性。TRUNCATE TABLE 是 PostgreSQL 中一种高效删除表内所有记录的方法。本文将详细探讨 PostgreSQL 中 TRUNCATE TABLE 的使用方法、性能优势以及注意事项。 什么是 …...

黑盒/白盒运维监控

运维监控分为黑盒和白盒 黑盒&#xff1a;不深入代码&#xff0c;在系统角度看TPS&#xff0c;延迟等指标 白盒&#xff1a;深入代码分析&#xff0c;通过日志捕捉&#xff0c;以及主动上报告警等来进行监控 黑盒监控&#xff1a; 1. 页面功能&#xff1a;域名是否可访问&…...

日志收集Day007

1.配置ES集群TLS认证: (1)elk101节点生成证书文件 cd /usr/share/elasticsearch ./bin/elasticsearch-certutil cert -out config/elastic-certificates.p12 -pass "" --days 3650 (2)elk101节点为证书文件修改属主和属组 chown elasticsearch:elasticsearch con…...

微信小程序1.1 微信小程序介绍

1.1 微信小程序介绍 内容提要 1.1 什么是微信小程序 1.2 微信小程序的功能 1.3 微信小程序使用场景 1.4 微信小程序能取代App吗 1.5 微信小程序的发展历程 1.6微信小程序带来的机会...