【C++指南】模板 深度解析
💓 博客主页:倔强的石头的CSDN主页
📝Gitee主页:倔强的石头的gitee主页
⏩ 文章专栏:《C++指南》
期待您的关注
目录
1. 引言
2. 模板的基本概念
3. 函数模板
3.1 定义和语法
3.2 函数模板实例化
3.3 隐式实例化
3.4 显式实例化
3.5 模板函数的匹配规则
4. 类模板
4.1 定义和语法
4.2 成员函数的定义
4.3 模板参数的默认值
5. 模板的高级用法
5.1 模板特化
5.2 模板模板参数
6. 实战案例
6.1 函数模板示例
6.2 类模板示例
7. 常见问题与注意事项
8. 结语
9. 参考文献
1. 引言
C++模板是一种强大的泛型编程工具,它允许程序员编写独立于具体类型的代码。
泛型编程:编写与类型无关的通用代码,是代码复用的一种手段。模板是泛型编程的基础。
通过模板,我们可以创建通用的函数和类,这些函数和类可以适用于多种数据类型,从而提高代码的复用性和灵活性。
本文将详细介绍C++模板的基本概念和使用方法。
2. 模板的基本概念
模板是C++的一种特性,用于创建函数或类的通用形式,这些形式可以应用于多种数据类型。
模板允许开发者编写一次代码,然后用不同的类型实例化,从而生成具体的函数或类。
3. 函数模板
3.1 定义和语法
函数模板的定义使用关键字template
,后跟模板参数列表,然后是函数声明或定义。模板参数列表通常包含一个或多个类型参数。
template<typename T1, typename T2,......,typename Tn>返回值类型 函数名(参数列表){}
template <typename T>
T max(T a, T b) {return (a > b) ? a : b;
}
注意:
typename是用来定义模板参数关键字,也可以使用class(切记:不能使用struct代替class)
3.2 函数模板实例化
用不同类型的参数使用函数模板时,称为函数模板的实例化。
模板参数实例化分为:隐式实例化 和显式实例化。
3.3 隐式实例化
当调用函数模板时,编译器会根据传递的参数类型自动推导出模板参数的具体类型。
这种实例化,称为隐式实例化,如下方示例:
#include<iostream>template <typename T>
T max(T a, T b) {return (a > b) ? a : b;
}int main() {int x = 3, y = 4;double a = 1.1, b = 2.2;int maxInt = max(x, y); // T 被推导为 intdouble maxDouble = max(a, b); // T 被推导为 doublestd::cout << "Max of " << x << " and " << y << " is " << maxInt << std::endl;std::cout << "Max of " << a << " and " << b << " is " << maxDouble << std::endl;return 0;
}
要注意的是:如果传递的参数不能让编译器正确推导出实例化的函数,就会报错
如下方示例:
#include<iostream>template <typename T>
T max(T a, T b) {return (a > b) ? a : b;
}int main() {int x = 3, y = 4;double a = 1.1, b = 2.2;int maxInt = max(x, a); // 编译报错std::cout << "Max of " << x << " and " << y << " is " << maxInt << std::endl;return 0;
}
注意:在模板中,编译器一般不会进行类型转换操作,因为一旦转化出问题,编译器就需要 背黑锅
此时有两种处理方式:1. 用户自己来强制转化 2. 使用显式实例化
int maxInt = max(x, (int)a); //强制类型转换
3.4 显式实例化
显式指定模板参数的类型,可以使用尖括号<>
来指定。
int main() {int x = 3, y = 4;double a = 1.1, b = 2.2;int maxInt = max<int>(x, y); // 显式指定 T 为 intdouble maxDouble = max<double>(a, b); // 显式指定 T 为 doublestd::cout << "Max of " << x << " and " << y << " is " << maxInt << std::endl;std::cout << "Max of " << a << " and " << b << " is " << maxDouble << std::endl;return 0;
}
3.5 模板函数的匹配规则
- 一个非模板函数可以和一个同名的函数模板同时存在,而且该函数模板还可以被实例化为这 个非模板函数。对于非模板函数和同名函数模板,如果其他条件都相同,在调动时会优先调用非模板函数而 不会从该模板产生出一个实例。普通函数的优先级高于模板函数
- 如果模板可以产生一个具有更好匹配的函数, 那么将选择模板
// 专门处理int的加法函数int Add(int left, int right){return left + right;}// 通用加法函数template<class T>T Add(T left, T right){return left + right;}void Test(){Add(1, 2); // 与非模板函数匹配,编译器不需要特化Add<int>(1, 2); // 调用编译器特化的Add版本}
4. 类模板
4.1 定义和语法
类模板的定义类似于函数模板,使用关键字template
,后跟模板参数列表,然后是类的定义。
template<class T1, class T2, ..., class Tn> class 类模板名{// 类内成员定义};
示例代码:
template <typename T>
class Stack {
private:T* items; // 数组存储元素int top; // 栈顶索引int size; // 栈的最大容量
public:Stack(int sz) : size(sz), top(-1) {items = new T[size];}~Stack() {delete[] items;}void push(const T& item);T pop();bool isEmpty() const;
};
4.2 成员函数的定义
类模板的成员函数可以在类内定义,也可以在类外定义。
注意:模版不建议声明和定义分离到两个文件.h 和.cpp会出现链接错误
// 在类内定义
template <typename T>
class Stack {
public:void push(const T& item) {if (top < size - 1) {items[++top] = item;} else {std::cout << "Stack overflow" << std::endl;}}T pop() {if (top >= 0) {return items[top--];} else {std::cout << "Stack underflow" << std::endl;return T(); // 返回默认构造的对象}}bool isEmpty() const {return top == -1;}
};// 在类外定义
template <typename T>
void Stack<T>::push(const T& item) {if (top < size - 1) {items[++top] = item;} else {std::cout << "Stack overflow" << std::endl;}
}template <typename T>
T Stack<T>::pop() {if (top >= 0) {return items[top--];} else {std::cout << "Stack underflow" << std::endl;return T(); // 返回默认构造的对象}
}template <typename T>
bool Stack<T>::isEmpty() const {return top == -1;
}
4.3 模板参数的默认值
模板参数可以有默认值,这样在实例化时可以省略某些参数。
template <typename T, int Size = 100>
class Stack {
private:T* items; // 数组存储元素int top; // 栈顶索引int size; // 栈的最大容量
public:Stack() : size(Size), top(-1) {items = new T[size];}~Stack() {delete[] items;}void push(const T& item);T pop();bool isEmpty() const;
};
注意:
模板参数可以是类型参数(如 typename T
)或非类型参数(如 int N
)。
非类型参数必须是编译时常量表达式,并且其类型通常是整型、枚举类型、指针类型或引用类型(指向对象的引用)
这里的 int Size = 100
实际上是一个非类型模板参数,它有一个默认值。这意味着当实例化这个模板类时,如果不提供第二个参数,Size
将默认为100。但是,请注意,这个参数是模板级别的,而不是对象级别的。也就是说,一旦模板被实例化(例如 Stack<int>
或 Stack<int, 200>
),该实例的 Size
值就是固定的,不能在运行时改变
5. 模板的高级用法
5.1 模板特化
模板特化允许为特定的类型提供特殊的实现。
// 全特化
template <>
class Stack<char> {
private:char* items; // 数组存储元素int top; // 栈顶索引int size; // 栈的最大容量
public:Stack(int sz) : size(sz), top(-1) {items = new char[size];}~Stack() {delete[] items;}void push(char item);char pop();bool isEmpty() const;
};// 部分特化(仅限类模板)
template <typename T, int Size>
class Stack<T*, Size> {
private:T** items; // 数组存储元素int top; // 栈顶索引int size; // 栈的最大容量
public:Stack() : size(Size), top(-1) {items = new T*[size];}~Stack() {delete[] items;}void push(T* item);T* pop();bool isEmpty() const;
};
5.2 模板模板参数
模板模板参数允许将一个模板作为另一个模板的参数。
template <template <typename, int> class Container, typename T, int Size>
class MyClass {Container<T, Size> container;
public:void add(const T& item) {container.push(item);}T remove() {return container.pop();}
};
6. 实战案例
6.1 函数模板示例
编写一个通用的数组排序函数。
#include <algorithm>template <typename T>
void sortArray(T arr[], int size) {std::sort(arr, arr + size);
}int main() {int intArr[] = {5, 2, 8, 1, 9};double doubleArr[] = {3.1, 2.2, 1.1, 5.5, 4.4};sortArray(intArr, 5);sortArray(doubleArr, 5);for (int i : intArr) {std::cout << i << " ";}std::cout << std::endl;for (double d : doubleArr) {std::cout << d << " ";}std::cout << std::endl;return 0;
}
6.2 类模板示例
编写一个通用的链表类。
template <typename T>
class LinkedList {
private:struct Node {T data;Node* next;Node(T val) : data(val), next(nullptr) {}};Node* head;
public:LinkedList() : head(nullptr) {}~LinkedList() {clear();}void insert(T value);void remove(T value);bool contains(T value) const;void clear();
};template <typename T>
void LinkedList<T>::insert(T value) {Node* newNode = new Node(value);if (!head) {head = newNode;} else {Node* current = head;while (current->next) {current = current->next;}current->next = newNode;}
}template <typename T>
void LinkedList<T>::remove(T value) {Node* current = head;Node* previous = nullptr;while (current) {if (current->data == value) {if (previous) {previous->next = current->next;} else {head = current->next;}delete current;return;}previous = current;current = current->next;}
}template <typename T>
bool LinkedList<T>::contains(T value) const {Node* current = head;while (current) {if (current->data == value) {return true;}current = current->next;}return false;
}template <typename T>
void LinkedList<T>::clear() {Node* current = head;while (current) {Node* next = current->next;delete current;current = next;}head = nullptr;
}int main() {LinkedList<int> list;list.insert(1);list.insert(2);list.insert(3);std::cout << "Contains 2: " << list.contains(2) << std::endl;list.remove(2);std::cout << "Contains 2: " << list.contains(2) << std::endl;return 0;
}
7. 常见问题与注意事项
- 编译时间增加:复杂的模板可能会显著增加编译时间。
- 错误信息复杂:模板错误可能导致难以理解的错误消息。
- 代码膨胀:模板的过度使用可能会导致目标文件中出现大量重复的代码。
8. 结语
C++模板是实现泛型编程的重要手段,它不仅增强了代码的复用性和可维护性,还提高了程序的执行效率。通过本文的学习,希望读者能够掌握C++模板的基本概念和使用方法,并在实际编程中灵活运用。
9. 参考文献
- Stroustrup, B. (2013). The C++ Programming Language. 4th Edition.
- Josuttis, N. M. (2012). The C++ Standard Library: A Tutorial and Reference. 2nd Edition.
- C++ Standard Library Documentation
希望这篇文章对你有所帮助,祝你在学习C++模板的过程中取得更大的进步!
相关文章:
【C++指南】模板 深度解析
💓 博客主页:倔强的石头的CSDN主页 📝Gitee主页:倔强的石头的gitee主页 ⏩ 文章专栏:《C指南》 期待您的关注 目录 1. 引言 2. 模板的基本概念 3. 函数模板 3.1 定义和语法 3.2 函数模板实例化 3.3 隐式实例化 …...
【traefik】forwadAuth中间件跨namespace请求的问题
前情提要 - fowardAuth鉴权中间件的使用: 【traefik】使用forwardAuth中间件做网关层的全局鉴权 1. 问题 我的 traefik-ingress-controller 所在 namespace: traefik 业务服务所在 namespace: apps 路由与 forwardAuth 中间件配置如下: # 路由 apiV…...
【25考研】西南交通大学软件工程复试攻略!
一、复试内容 复试对考生的既往学业情况、外语听说交流能力、专业素质和科研创新能力,以及综合素质和一贯表现等进行全面考查,主要考核内容包括思想政治素质和道德品质、外语听说能力、专业素质和能力,综合素质及能力。考核由上机考试和面试两部分组成&a…...
在 Safari 浏览器中,快速将页面恢复到 100% 缩放(也就是默认尺寸)Command (⌘) + 0 (零)
在 Safari 浏览器中,没有一个专门的快捷键可以将页面恢复到默认的缩放比例。 但是,你可以使用以下两种方法快速将页面恢复到 100% 缩放(也就是默认尺寸): 方法一:使用快捷键 (最常用) Command (⌘) 0 (零…...
linux的大内核锁与顺序锁
大内核锁 Linux大内核锁(Big Kernel Lock,BKL)是Linux内核中的一种锁机制,用于保护内核资源,以下是关于它的详细介绍: 概念与作用 大内核锁是一种全局的互斥锁,在同一时刻只允许一个进程访问…...
CVE-2025-22777 (CVSS 9.8):WordPress | GiveWP 插件的严重漏洞
漏洞描述 GiveWP 插件中发现了一个严重漏洞,该插件是 WordPress 最广泛使用的在线捐赠和筹款工具之一。该漏洞的编号为 CVE-2025-22777,CVSS 评分为 9.8,表明其严重性。 GiveWP 插件拥有超过 100,000 个活跃安装,为全球无数捐赠平…...
牛客周赛 Round 76题解
小红出题 思路:我们发现,每七天可以获得15元,那么我们可以对7取模,看能有多少7的倍数,然后剩下的就是看是否超过5,超过5就直接15,否则加上天数*3 #include<bits/stdc.h> using namespace…...
【ARM】MDK如何将变量存储到指定内存地址
1、 文档目标 通过MDK的工程配置,将指定的变量存储到指定的内存地址上。 2、 问题场景 在项目工程的开发过程中,对于flash要进行分区,需要规划出一个特定的内存区域来存储变量。 3、软硬件环境 1)、软件版本:MDK 5.…...
解决在arm架构下的欧拉操作系统mysql8.4.2源码安装
目标:在欧拉的22.03 (LTS-SP4)版本操作系统,cpu的架构为ARM,源码安装mysql-8.4.2。 1.查看操作系统 # cat /etc/os-release NAME"openEuler" VERSION"22.03 (LTS-SP4)"# uname -i aarch642.mysql下载地址 mysql的下载…...
SpringAop
SpringAop aop定义核心概念aop基础实现执行流程 aop进阶通知类型切入点表达式的抽取通知的执行顺序切入点表达式execution方式实现annotation注解方式实现示例 笔记链接 aop定义 AOP:Aspect Oriented Programming(面向切面编程、面向方面编程)…...
C++内存泄露排查
内存泄漏是指程序动态分配的内存未能及时释放,导致系统内存逐渐耗尽,最终可能造成程序崩溃或性能下降。在C中,内存泄漏通常发生在使用new或malloc等分配内存的操作时,但没有正确地使用delete或free来释放这块内存。 在日常开发过程…...
Cesium小知识:pointPrimitive collection 详解
Cesium.PointPrimitiveCollection 是 Cesium 中用于高效管理和渲染大量点(points)的一个类。它允许你创建和管理大量的 PointPrimitive 实例,这些实例可以用来表示地理空间中的点数据,如传感器位置、车辆位置、兴趣点等。与直接使用 Cesium.Entity 相比,PointPrimitiveCol…...
从 Conda 到 Pip-tools:Python 依赖管理全景探索20250113
从 Conda 到 Pip-tools:Python 依赖管理全景探索 引言 在 Python 开发中,依赖管理是一个"常见但复杂"的问题:一次简单的版本冲突可能让团队调试数小时;一次不受控的依赖升级可能让生产环境瘫痪。随着项目规模的增加和…...
浅谈云计算01 | 云计算服务的特点
在当今数字化时代,云计算作为一种强大的技术解决方案,正逐渐改变着企业和个人对信息技术的使用方式。本文将详细探讨云计算的五个主要特点,包括按需自助服务、广泛的网络接入、资源池化、快速弹性伸缩以及可计量服务。 一、按需自助服务 云…...
2025年,华为认证HCIA、HCIP、HCIE 该如何选择?
眼看都到 2025 年啦,华为认证还吃香不? 把这问题摆在每个网络工程师跟前,答案可没那么容易说清楚。 到底考不考它值当不值当,重点在于您自己的职业规划,还有对行业走向的领会。 2025 年华为认证仍然值得一考&#…...
使用Selenium进行网页自动化测试
在使用Selenium进行网页自动化测试时,获取网络请求数据(即network数据)并不直接由Selenium库提供。Selenium主要用于与网页内容进行交互(如点击、输入文本、获取页面元素等),但它本身不拦截或记录网络请求。…...
Linux 下 mtrace 的详细介绍
在 Linux 系统中,内存管理是操作系统的一项重要任务,而内存泄漏(Memory Leak)是开发过程中常见且棘手的问题之一。为了帮助开发者追踪和调试内存泄漏问题,mtrace 提供了一种有效的方式来检测和分析内存的分配与释放情况…...
【DB-GPT】开启数据库交互新篇章的技术探索与实践
一、引言:AI原生数据应用开发的挑战与机遇 在数字化转型的浪潮中,企业对于智能化应用的需求日益增长。然而,传统的数据应用开发方式面临着诸多挑战,如技术栈复杂、开发周期长、成本高昂、难以维护等。这些问题限制了智能化应用的…...
深入 Flutter 和 Compose 在 UI 渲染刷新时 Diff 实现对比
众所周知,不管是什么框架,在前端 UI 渲染时,都会有构造出一套相关的渲染树,并且在 UI 更新时,为了尽可能提高性能,一般都只会进行「差异化」更新,而不是对整个 UI Tree 进行刷新,所以…...
Android 网络层相关介绍
关注 Android 默认支持的网络管理行为,默认支持的网络服务功能。 功能术语 术语缩写全称释义DHCPv6Dynamic Host Configuration Protocol for IPv6动态主机配置协议的第六版,用于在IPv6网络中动态分配IP地址和其他网络配置参数。DNS Domain Name System域名系统。LLALink-Loc…...
ThreeJs开发环境安装与首个DEMO
安装开发环境 我这边使用的JetBrain的WebStorm,咨询过很多其他开发从业者,普遍使用vscode的比较多。但是考虑到vscode涉及到不少插件安装和IDE配置,作为傻瓜式入门,我这边采用WebStorm。 下载地址: WebStorm: The J…...
【Vim Masterclass 笔记09】S06L22:Vim 核心操作训练之 —— 文本的搜索、查找与替换操作(第一部分)
文章目录 S06L22 Search, Find, and Replace - Part One1 从光标位置起,正向定位到当前行的首个字符 b2 从光标位置起,反向查找某个字符3 重复上一次字符查找操作4 定位到目标字符的前一个字符5 单字符查找与 Vim 命令的组合6 跨行查找某字符串7 Vim 的增…...
js:根据后端返回数据的最大值进行计算然后设置这个最大值为百分之百,其他的值除这个最大值
问: 现在tabData.value 接收到了后端返回的数据, [{text:人力,percentage:‘90’},{text:物品,percentage:‘20’},{text:物理,percentage:‘50’},{text:服务,percentageÿ…...
线形回归与小批量梯度下降实例
1、准备数据集 import numpy as np import matplotlib.pyplot as pltfrom torch.utils.data import DataLoader from torch.utils.data import TensorDataset######################################################################### #################准备若干个随机的x和…...
【数学】概率论与数理统计(三)
文章目录 [toc] 随机变量的概念随机事件数量化随机变量 离散型随机变量及其概率分布随机变量的分类离散型随机变量离散型随机变量的常见分布两点分布二项分布泊松分布泊松定理证明 泊松分布 超几何分布几何分布 连续型随机变量及其概率分布连续型随机变量零概率事件几乎必然发生…...
如何在 Linux、MacOS 以及 Windows 中打开控制面板
控制面板不仅仅是一系列图标和菜单的集合;它是通往优化个人计算体验的大门。通过它,用户可以轻松调整从外观到性能的各种参数,确保他们的电脑能够完美地适应自己的需求。无论是想要提升系统安全性、管理硬件设备,还是简单地改变桌…...
《AI赋能鸿蒙Next,开启智能关卡设计新时代》
在游戏开发领域,关卡设计是至关重要的一环,它直接影响着玩家的游戏体验和沉浸感。而随着人工智能技术的飞速发展,结合鸿蒙Next系统的强大功能,为游戏的智能关卡设计带来了全新的思路和方法。 利用AI学习玩家行为模式 在鸿蒙Next…...
Safari浏览器上ico图标显示不出来,怎么解决?
Safari浏览器上ico图标显示不出来,怎么解决? 如果Safari浏览器上ico图标显示不出来了,如下图,该图标显示为灰色。 可以关闭Safari浏览器,并清除历史记录,就可以解决啦。 另外,如果多个网站这…...
Java Bean Validation 不适用Spring的情况下自定义validation注解
Java Bean Validation(也称为 JSR 380,为 Bean Validation 2.0 规范)提供了一套基本的注解,用于定义和验证 Java Bean 的属性。例如: NotNull:属性不能为空 Size:字符串、集合或数组的大小有约…...
【算法学习笔记】30:埃氏筛(Sieve of Eratosthenes)和线性筛(Linear Sieve)
测试题目:AcWing 868. 筛质数 埃氏筛(Sieve of Eratosthenes) 如果 i i i是素数,每次把 i i i的倍数都筛掉,存在重复筛选,时间复杂度 n ⋅ l o g ( l o g n ) n \cdot log(logn) n⋅log(logn)。 #includ…...
风控业务——评分模型
本文主要讲述了金融机构风控模型的重要性及其应用。首先,开头概述了风控模型的整体建模流程,包括特征工程和建模方法。接着,本文强调了贷前、贷中、贷后三个阶段中风控模型的应用,如信用评分、行为评分和催收评分。同时还提到了信…...
jupyter notebook练手项目:线性回归——学习时间与成绩的关系
线性回归——学习时间与学习成绩的关系 第1步:导入工具库 pandas——数据分析库,提供了数据结构(如DataFrame和Series)和数据操作方法,方便对数据集进行读取、清洗、转换等操作。 matplotlib——绘图库,p…...
DDD - 微服务设计与领域驱动设计实战(上)_统一建模语言及事件风暴会议
文章目录 Pre概述业务流程需求分析的困境统一语言建模事件风暴会议什么是事件风暴(Event Storming)事件风暴会议 总结 Pre DDD - 软件退化原因及案例分析 DDD - 如何运用 DDD 进行软件设计 DDD - 如何运用 DDD 进行数据库设计 DDD - 服务、实体与值对…...
《自动驾驶与机器人中的SLAM技术》ch7:基于 ESKF 的松耦合 LIO 系统
目录 基于 ESKF 的松耦合 LIO 系统 1 坐标系说明 2 松耦合 LIO 系统的运动和观测方程 3 松耦合 LIO 系统的数据准备 3.1 CloudConvert 类 3.2 MessageSync 类 4 松耦合 LIO 系统的主要流程 4.1 IMU 静止初始化 4.2 ESKF 之 运动过程——使用 IMU 预测 4.3 使用 IMU 预测位姿进…...
day07_Spark SQL
文章目录 day07_Spark SQL课程笔记一、今日课程内容二、Spark SQL函数定义(掌握)1、窗口函数2、自定义函数背景2.1 回顾函数分类标准:SQL最开始是_内置函数&自定义函数_两种 2.2 自定义函数背景 3、Spark原生自定义UDF函数3.1 自定义函数流程&#x…...
【LC】2270. 分割数组的方案数
题目描述: 给你一个下标从 0 开始长度为 n 的整数数组 nums 。 如果以下描述为真,那么 nums 在下标 i 处有一个 合法的分割 : 前 i 1 个元素的和 大于等于 剩下的 n - i - 1 个元素的和。下标 i 的右边 至少有一个 元素,也就是…...
Docker 容器通信的网络模式详解
Docker 的网络模式是容器化技术中非常重要的一部分,它决定了容器之间以及容器与外部世界如何通信。Docker 提供了多种网络模式,每种模式都有其特定的使用场景和优势。本文将深入探讨 Docker 的网络模式,包括桥接模式、主机模式、覆盖网络模式…...
Apache和PHP:构建动态网站的黄金组合
在当今的互联网世界,网站已经成为了企业、个人和机构展示自己、与用户互动的重要平台。而在这些动态网站的背后,Apache和PHP无疑是最受开发者青睐的技术组合之一。这一组合提供了高效、灵活且可扩展的解决方案,帮助您快速搭建出强大的网站&am…...
一个简单的html5导航页面
一个简单的 HTML5 导航页面的示例代码: html <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><ti…...
积木仪表盘 出现 “没有权限,请联系管理员分配权限“ 解决方法
目录 前言1. 问题所示2. 解决方法前言 🤟 找工作,来万码优才:👉 #小程序://万码优才/r6rqmzDaXpYkJZF 原先写过报表的错误!但错误解决方式不一样:jmreport测试数据库出现 权限不足,此功能需要分配角色 解决方法 1. 问题所示 出现 没有权限,请联系管理员分配权限 的…...
C++语言的循环实现
C语言中的循环实现 引言 在程序设计中,循环是一个至关重要的概念。它允许我们在满足某种条件时重复执行某段代码,从而实现复杂的逻辑和算法。C作为一种强大的编程语言,提供了多种循环结构来满足不同的需求。本文将深入探讨C中的循环实现&am…...
高级java每日一道面试题-2025年01月13日-框架篇[Spring篇]-Spring 是怎么解决循环依赖的?
如果有遗漏,评论区告诉我进行补充 面试官: Spring 是怎么解决循环依赖的? 我回答: 在Java高级面试中,Spring框架如何解决循环依赖是一个重要且常见的问题。以下是对Spring解决循环依赖的详细解释: 循环依赖的定义与类型 循环依赖是指两个或多个Bea…...
.Net Core Record 类型
public class Person { public string id {get;init;} public string code {get;init;} public string name {get;init;} } //Person 属性不可单独赋值,相当于使用record定义 public record Person string id,string code,string name) //record类…...
GitLab CI/CD使用runner实现自动化部署前端Vue2 后端.Net 7 Zr.Admin项目
1、查看gitlab版本 建议安装的runner版本和gitlab保持一致 2、查找runner 执行 yum list gitlab-runner --showduplicates | sort -r 找到符合gitlab版本的runner,我这里选择 14.9.1版本 如果执行出现找不到下载源,添加官方仓库 执行 curl -L &quo…...
重邮+数字信号处理实验七:用 MATLAB 设计 IIR 数字滤波器
一、实验目的 1 、加深对窗函数法设计 FIR 数字滤波器的基本原理的理解。 2 、学习用 Matlab 语言的窗函数法编写设计 FIR 数字滤波器的程序。 3 、了解 Matlab 语言有关窗函数法设计 FIR 数字滤波器的常用函数用法。 4 、掌握 FIR 滤波器的快速卷积实现原理。…...
CES 2025:INAIR 推出“另类”AR电脑,重新定义移动计算体验
在2025年国际消费类电子产品展览会(CES)上,INAIR公司凭借其创新的AR电脑产品吸引了众多目光。这款设备不仅融合了增强现实(AR)技术与传统个人电脑的功能,还通过独特的设计理念为用户带来了前所未有的移动计算体验。本文将详细介绍INAIR AR电脑的特点、技术创新及其对未来…...
了解 ASP.NET Core 中的中间件
在 .NET Core 中,中间件(Middleware) 是处理 HTTP 请求和响应的核心组件。它们被组织成一个请求处理管道,每个中间件都可以在请求到达最终处理程序之前或之后执行操作。中间件可以用于实现各种功能,如身份验证、路由、…...
数据结构与算法之链表: LeetCode 234. 回文链表 (Ts版)
回文链表 https://leetcode.cn/problems/palindrome-linked-list/description/ 描述 给你一个单链表的头节点 head ,请你判断该链表是否为回文链表如果是,返回 true ;否则,返回 false 示例 1 输入:head [1,2,2,1]…...
DVWA靶场CSRF漏洞通关教程及源码审计
目录标题 CSRFlow源码审计 medium源码审计 high源码审计 impossible源码审计 CSRF low 先修改密码 看到地址栏 复制在另一个网页打开 成功登录 源码审计 没有任何过滤措施,很危险,并且采用了不安全的md5加密 <?phpif( isset( $_GET[ Change ] )…...
支持Google Analytics快捷添加的CMS:费用与部署形式详解
CMS 的费用和部署形式是选择平台的重要参考因素,不同的业务需求需要不同的解决方案。本文将从费用和部署形式两个角度,详细分析支持 Google Analytics 快捷集成的 CMS 和工具,帮助您更好地了解这些平台的特点。 1. BigCommerce 费用ÿ…...