随笔分类 -  编程

摘要:C++ 完美转发是泛型编程里一个关键特性,用来在模板函数中保持参数的“原始值类别”(lvalue/rvalue)和属性(const、引用)。 背景 在模板编程中,函数参数往往需要被“原封不动”地传递到另一个函数。例如: 如果传入的是左值,就要继续作为左值传给目标函数; 如果传入的是右值,就要继续作为 阅读全文
posted @ 2025-10-08 11:31 木杉的园子 阅读(38) 评论(0) 推荐(0)
摘要:C++11 引入了移动语义,它的出现主要是为了解决对象频繁拷贝带来的性能开销问题。移动语义的核心思想是:当对象的资源不再需要时,可以“转移”它的内部资源,而不是进行昂贵的深拷贝。 背景 在传统 C++ 中,函数参数传递或者返回值通常依赖拷贝构造函数。比如,在调用函数前,通常需要在调用者的作用域中创建 阅读全文
posted @ 2025-10-08 11:11 木杉的园子 阅读(43) 评论(0) 推荐(0)
摘要:在 C++ 中,指针(Pointer)和引用(Reference)都用于间接访问变量,但是它们在语法和语义上都有显著的差异。指针是一个变量,它可以保存另一个变量的内存地址;引用是另一个变量的别名,由编译器进行处理,使用时与使用原变量无异。 指针和引用使用的一些差异如下: 初始化 指针:可以先定义后赋 阅读全文
posted @ 2025-10-08 09:44 木杉的园子 阅读(63) 评论(0) 推荐(0)
摘要:当缓存容量固定时,我们需要一种淘汰策略:每次访问把数据标记为“最近使用”,当容量满了时淘汰“最久未使用”的那个,以提升缓存命中率。这就是 LRU 的核心。 以下是一个使用 C++ 实现的 LRU Cache 模版,拥有以下特性: 使用 std::list 维护一个缓存列表,头部的缓存块为最近使用的、 阅读全文
posted @ 2025-09-03 17:02 木杉的园子 阅读(63) 评论(0) 推荐(0)
摘要:11. 盛最多水的容器 - 力扣(LeetCode) 给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。 找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。 返回容器可以储存的最大水量。 说明 阅读全文
posted @ 2025-05-15 16:32 木杉的园子 阅读(29) 评论(0) 推荐(0)
摘要:以下是 0423 机试记录。 图像亮度坐标搜索 给定一张二维图像,图像中每个值表示该坐标下的亮度。现在给定一个亮度值 \(m\),请返回离图像中心坐标最近的 \(k\) 个亮度为 \(m\) 的坐标 \((x, y)\)。 提示: 图像中元素的坐标范围 \(x : [0, w - 1]\),\(y 阅读全文
posted @ 2025-05-15 16:31 木杉的园子 阅读(48) 评论(0) 推荐(0)
摘要:在 C++ 编程中一般使用 std::thread 来进行创建多个线程,实现并发执行、提升程序性能。 1. 线程的创建和启动 最简单的方式就是将一个可调用对象(函数、函数对象、lambda 表达式)传给 std::thread 构造函数: #include <iostream> #include < 阅读全文
posted @ 2025-04-27 14:43 木杉的园子 阅读(151) 评论(0) 推荐(0)
摘要:在多线程编程中,使用互斥锁能够避免数据竞争。在 C++ 标准库中有 std::mutex 的互斥锁实现来帮助我们处理线程同步。 1. 互斥锁的基本用法 在 C++ 11 中,引入了 RAII (Resource Acquisition Is Initialization)风格的锁管理类 std::l 阅读全文
posted @ 2025-04-27 14:39 木杉的园子 阅读(144) 评论(0) 推荐(0)
摘要:在 C 语言编程中,类型转换的方式非常简单,只有两种方法。第一种是隐式类型转换,这由编译器自动进行,比如: float x = 10; // Convert int to float 第二种是显式类型转换,由程序指定,比如: int x = (int)3.14; // Convert float t 阅读全文
posted @ 2025-04-19 23:57 木杉的园子 阅读(101) 评论(0) 推荐(0)
摘要:在 C 语言编程中,使用裸指针(raw pointer)几乎是处理动态内存的唯一方式。然而,随着 C++ 的不断演进,特别是在 C++11 及之后的标准中,智能指针(std::unique_ptr, std::shared_ptr, std::weak_ptr)和引用(&)成为了更安全、更现代的替代 阅读全文
posted @ 2025-04-19 23:28 木杉的园子 阅读(66) 评论(0) 推荐(0)
摘要:在 C 语言中,所有的全局变量、函数和宏定义都位于同一个全局命名空间中,随着项目规模的扩大,这种方式容易造成名称冲突和命名污染。而 C++ 引入了 namespace(命名空间)机制,有效解决了这些问题,提升了代码的可组织性、模块化和可维护性。 C 语言编程中的命名冲突 举一个简单的例子:假设我们需 阅读全文
posted @ 2025-04-19 22:13 木杉的园子 阅读(61) 评论(0) 推荐(0)
摘要:在 C 语言中,开发者常常使用 #define 预处理指令来定义常量、宏函数或条件编译开关。而在 C++ 编程中,我们应尽量使用语言本身的特性以确保安全性和可控性。 "#define" 的局限性 缺乏类型检查: #define PI 3.1415926 #define SQUARE(x) (x)*( 阅读全文
posted @ 2025-04-19 10:56 木杉的园子 阅读(65) 评论(0) 推荐(0)
摘要:在 C++ 中,new 是我们最常用的内存分配方式之一。很多初学者会以为 new 只是一个语法糖,用来代替 C 语言的 malloc,但实际上,new 背后涉及的是一整套机制,其中包括 operator new、placement new 等概念。 1. new 我们一般使用以下语句创建一个对象: 阅读全文
posted @ 2025-04-18 23:35 木杉的园子 阅读(152) 评论(0) 推荐(0)
摘要:Dijkstra 算法是解决图论最短路径问题的经典算法,本文将介绍使用优先队列优化的 Dijkstra 算法。 1. Dijkstra 算法的基本步骤 Dijkstra 算法适用于非负权重的有向或无向图,其核心思路是: 初始化:将源点到自身的距离设为 0,到其他所有顶点的距离设为无穷大; 重复以下操 阅读全文
posted @ 2025-04-18 22:33 木杉的园子 阅读(622) 评论(0) 推荐(0)
摘要:如果需要在程序中频繁地创建和删除小对象,如果直接对内存进行操作可能会造成较大的时间开销和内部碎片,而对象池是针对这一场景的有效优化手段。通过提前分配一定数量的对象在对象池中,并在需要时从池中获取对象,使用完毕后再归还给池,可以减少动态分配内存的次数,避免频繁的创建和销毁操作,从而提高性能和资源利用率 阅读全文
posted @ 2025-04-18 16:57 木杉的园子 阅读(130) 评论(0) 推荐(0)
摘要:在各大公司的机试中,常见的答题模式有 核心模式 与 ACM 模式。核心模式通常是一些在线测试平台(如力扣、牛客等)上使用的答题模式,需要答题者在函数体完成代码,函数的输入输出都是固定的,以供测试代码调用。ACM 模式需要答题者自行处理输入输出,通常以标准输入输出格式表示。下面以 C++ 为例展示 A 阅读全文
posted @ 2025-04-13 22:44 木杉的园子 阅读(382) 评论(0) 推荐(0)
摘要:在 C++ 中,自定义比较函数通常有几种方法,主要通过以下几种方式来实现: 方法一:使用标准库函数对象 #include <iostream> #include <string> #include <map> int main() { // 使用标准库中预定义的比较器 std::map<int, s 阅读全文
posted @ 2025-02-26 14:11 木杉的园子 阅读(157) 评论(0) 推荐(0)
摘要:在 C++ 中,匿名函数(通常是指 lambda 表达式)是无法直接递归调用自己的,因为匿名函数本身没有名字。然而,可以通过以下几种方法间接实现递归调用: 方法一:通过 std::function 来递归调用 #include <iostream> #include <functional> int 阅读全文
posted @ 2025-02-25 20:39 木杉的园子 阅读(126) 评论(0) 推荐(0)