C语言中的内存函数
目录
- 1 memcpy()函数的基本信息及功能
- (1) void * destination
- (2) const void * source
- (3) size_t num
- 1.2 memcpy()函数实战演练
- 1.3 memcpy()函数的模拟实现
- 1.3.1 my_memcpy()函数定义及参数
- 1.3.2 my_memcpy()函数函数体
- 1.3.3 my_memcpy()函数拷贝元素堆叠
- 2 memmove()函数的基本信息及功能
- 2.1 memmove()函数实战演练
- 2.2 memmove()函数的模拟实现
- 2.2.1 my_memmove()函数定义及参数
- 3 memset()函数的基本信息及功能
- (1)void * ptr
- (2)int value
- (3)size_t num
- 3.1 memset()函数实战演练
- 3.2 memset()函数能否把整型数组中的元素全部替换为1
- 4 memcmp()函数的基本信息及功能
- (1)const void * ptr1
- (2)const void * ptr2
- (3)size_t num
- 4.1 memcmp()函数实战演练
- 4.1.1 memcmp()不提前结束
- 4.1.2 memcmp()提前结束
1 memcpy()函数的基本信息及功能
我们从cplusplus官网(cplusplus(C语言函数查询网站)上我们不难看到memcpy()函数是有三个参数如图:
memcpy函数拷贝结束后,会返回目标空间的起始地址类型是(void *)
1、函数memcpy从source的位置开始向后复制num个字节的数据到destination指向的内存位置。
2、该函数在遇到’\0’字符时不会停止执行。需要注意的是,与strcpy()函数不同,strcpy()专门用于字符串的复制操作,而memcpy()则适用于任意数据类型的复制。
下面我们对每个参数进行详细解释。
(1) void * destination
调用该函数时,需将目的地数组的地址作为第一个参数传入,该地址将由 void * 类型的指针destination 接收。需要注意的是,void * 类型的指针是一种无具体类型的指针,能够接受任何数据类型的地址,因此 memcpy() 函数可以实现任意数据类型之间的拷贝。
(2) const void * source
将源数组的地址作为第二个参数传入,该地址由 const void * 类型的指针 source 接收(const 位于 * 左侧,表示不能对指针进行解引用操作)。
(3) size_t num
1、要复制的字节数。
2、size_t 是无符号整型。
1.2 memcpy()函数实战演练
我们下面使用memcpy()函数进行一个整型数组的拷贝,两个数组如下:
int arr1[] = { 1, 2, 3, 4, 5 , 6, 7, 8, 9, 10 };//源头int arr2[20] = { 0 };//目的地
接下来我们将调用标准库中的memcpy()函数,实现数组元素的复制作。具体操作是将arr1数组的前5个元素复制到arr2数组中。调用时需传入三个参数:
目标数组arr2、源数组arr1,以及要复制的字节数5*sizeof(int)。这里需要注意的是,字节数等于要复制的元素数量乘以每个元素所占的字节大小。
完整代码如下:
#include <stdio.h>
#include <string.h>
int main() {int arr1[] = { 1, 2, 3, 4, 5 , 6, 7, 8, 9, 10 };//源头int arr2[20] = { 0 };//目的地//目标将arr1数组中的前5个元素拷贝到arr2数组中//memcpy - 针对内存块进行拷贝//memcpy函数拷贝结束后,会返回目标空间的起始地址int* ret = memcpy(arr2, arr1, 5*sizeof(int));int i = 0;for (i = 0; i <= 19; i++) {printf("%d ", *(ret+i));}return 0;
}
运行结果:
1.3 memcpy()函数的模拟实现
掌握了memcpy()函数的基本用法后,接下来我们将尝试模拟实现它,编写一个自定义的my_memcpy()函数。
1.3.1 my_memcpy()函数定义及参数
首先,设计函数的三个参数, 因为要模拟实现 memcpy()函数,因此直接 仿照memcpy()函数的参数即可:
void* my_memcpy(void* dest, const void* src, size_t num)
1.3.2 my_memcpy()函数函数体
//memcpy()函数的模拟实现
void* my_memcpy(void* dest, const void* src, size_t num) {void* ret = dest;assert(dest && src);while (num--){*(char *)dest = *(char *)src;//指针加1的第一种写法//dest = (char*)dest + 1;//src = (char*)src + 1;指针加1的第二种写法((char* )dest)++;((char*)src)++;//(char *)dest++错误写法,dest指针只是临时转换为char * 指针并没有使用,本质还是void *类型指针,无法进行操作}return ret;
}
为了实现任意数据类型的拷贝,由于无法预知dest 和 src参数的具体类型,我们将其声明为 void * 类型。 void * 是一种无具体类型的指针,能够接收任何类型的地址。然而,由于 void * 指针无法直接解引用或进行整数加减运算,我们需要将其统一强制转换为 char * 类型。这种转换使得我们可以将内存视为按字节操作的空间,从而逐字节进行拷贝。
在拷贝过程中,我们需要处理 num 个元素。由于 char * 类型的指针每次解引用只能操作(拷贝)一个字节,因此外层需要使用 while 循环,循环次数为待拷贝的元素个数乘以每个元素的大小。
该部分完整代码如下:
#include <stdio.h>
#include <assert.h>
//memcpy()函数的模拟实现
void* my_memcpy(void* dest, const void* src, size_t num) {void* ret = dest;assert(dest && src);while (num--){*(char *)dest = *(char *)src;//指针加1的第一种写法//dest = (char*)dest + 1;//src = (char*)src + 1;指针加1的第二种写法((char* )dest)++;//(char *)dest++错误写法,dest指针只是临时转换为char * 指针并没有使用,本质还是void *类型指针,无法进行操作((char*)src)++;}return ret;
}
int main() {int arr1[] = { 1, 2, 3, 4, 5 , 6, 7, 8, 9, 10 };//源头int arr2[20] = { 0 };//目的地//my_memcpy(arr2, arr1, 20);//数组下标法int *ret = my_memcpy(arr2, arr1, 20);//指针法打印int i = 0;int size = 0;size = sizeof(arr2) / sizeof(arr2[0]);//计算数组的大小//打印方法(数组下标进行打印): //for ( i = 0; i < size; i++)//{// printf("%d ", arr2[i]);//}//打印方法(用函数返回值——>指针进行打印)for (i = 0; i <= 19; i++) {printf("%d ", *(ret+i));}return 0;}
1.3.3 my_memcpy()函数拷贝元素堆叠
如果source和destination有任何的重叠,复制的结果都是未定义的。
//探究 ——> 如果source和destination有任何的重叠,复制的结果都是未定义的。
void* my_memcpy(void* dest, const void* src, size_t num)
{void* ret = dest;int i = 0;assert(dest && src);while (num--){*(char*)dest = *(char*)src;((char*)src)++;((char*)dest)++;}return ret;
}int main()
{int arr1[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };my_memcpy(arr1 + 2, arr1, 20);//arr1[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }//预期效果: 1 2 1 2 3 4 5 8 9 10//实际效果: 1 2 1 2 1 2 1 8 9 10int i = 0;for ( i = 0; i < 10; i++){printf("%d ", arr1[i]);}return 0;
}
该情况如图
运行结果:
当源空间和目标空间出现重叠时,需要使用接下来介绍的memmove()函数。
2 memmove()函数的基本信息及功能
我们从cplusplus官网(cplusplus(C语言函数查询网站)上我们不难看到memmove()函数是有三个参数如图:
memmove() 函数的参数与memcpy() 函数 完全一致,两者的主要区别在于 memmove() 能够正确处理源内存块和目标内存块重叠的情况。
Tips:如果源空间和⽬标空间出现重叠,就得使用memmove函数处理。
2.1 memmove()函数实战演练
我们下面使用memmove()函数进行一个整型数组(源空间和⽬标空间出现重叠)的拷贝,如下:
//memcpy()函数实战演练
int main()
{int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };memmove(arr + 2, arr, 5 * sizeof(int));int i = 0;for ( i = 0; i < 10; i++){printf("%d ", arr[i]);}return 0;
}
这两个数组在拷贝时存在元素重叠的情况。
arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
预期效果:1 2 1 2 3 4 5 8 9 10
堆叠效果:1 2 1 2 1 2 1 8 9 10
这个时候,我们就要用到memcpy() 函数进行拷贝
运行结果:
2.2 memmove()函数的模拟实现
掌握了memmove()函数的基本用法后,接下来我们将尝试模拟实现它,编写一个自定义的my_memmove()。
2.2.1 my_memmove()函数定义及参数
首先,设计函数的三个参数, 因为要模拟实现memmove()函数,因此直接 仿照memmove()函数的参数即可:
void* my_memcpy(void* dest, const void* src, size_t num)
my_memmove()函数的实现思路与my_memcpy()函数基本一致,但增加了对内存重叠情况的处理。根据源地址与目标地址的相对位置,主要存在以下三种重叠情形:
情况一:src > dest(内存有重叠)
情况二:src < dest(内存有重叠)
情况三:src < dest(内存无重叠)
综上我们可以把上述三种情况总结为:
1、 当目标地址位于图中区域1时,采用从前向后的顺序进行拷贝;
2、当目标地址位于图中区域2时,采用从后向前的顺序进行拷贝;
3、当目标地址位于图中区域3时,可选择从前向后或从后向前的顺序进行拷贝。
因为,数组随着下标的增加地址是由低到高变化的。于是,我们判断重叠机制就有以下两种写法:
第一种写法:
若目标地址 dest 小于源地址 src,则从前向后执行拷贝操作;反之,则从后向前进行拷贝。
代码如下:
void* my_memcpy(void* dest, const void* src, size_t num) {void* ret = dest;assert(dest && src);if (dest < src)//从前往后进行拷贝{while (num--){*((char*)dest) = *((char*)src);dest = (char*)dest + 1;src = (char*)src + 1;}}else//从前往后进行拷贝{while (num--) {*((char*)dest + num) = *((char*)src + num);}}return ret;
}
第二种写法:
当 dest 地址位于 src 地址之前,或超过 src 加上拷贝元素个数的地址范围时,采用从前向后的拷贝方式;其余情况则一律从后向前进行拷贝。
代码如下:
//方法2
void* my_memcpy(void* dest, const void* src, size_t num) {void* ret = dest;assert(dest && src);if (dest < src || dest >= (char *)src + num)//从前往后{while(num--){*((char*)dest) = *((char*)src);dest = (char*)dest + 1;src = (char*)src + 1;}}else//从后往前{while (num--){*((char*)dest + num) = *((char*)src + num);}}return ret;
}
如何进行从后到前的拷贝呢?关键是要找到源数组和目标数组的最后一个,元素下面通过图示进行讲解。假设需要将源数组中的5个元素拷贝到目标数组中。
如图所示,当需要拷贝5个元素时,我们只需将src指针向后移动5 * sizeof(int) - 1次,即可定位到待拷贝元素的最后一个位置。同理,dest指针经过相同次数的移动后,也能指向目标位置的最后一个元素(5个元素中的最后一个元素)。
完整代码如下:
//方法一
void* my_memcpy(void* dest, const void* src, size_t num) {void* ret = dest;assert(dest && src);if (dest < src)//从前往后进行拷贝{while (num--){*((char*)dest) = *((char*)src);dest = (char*)dest + 1;src = (char*)src + 1;}}else//从前往后进行拷贝{while (num--) {*((char*)dest + num) = *((char*)src + num);}}return ret;
}//方法2
//void* my_memcpy(void* dest, const void* src, size_t num) {
// void* ret = dest;
// assert(dest && src);
// if (dest < src || dest >= (char *)src + num)//从前往后
// {
// while(num--)
// {
// *((char*)dest) = *((char*)src);
// dest = (char*)dest + 1;
// src = (char*)src + 1;
// }
// }
// else//从后往前
// {
// while (num--)
// {
// *((char*)dest + num) = *((char*)src + num);
// }
// }
// return ret;
//}
//int main()
{int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };//使用自己的memcpy()函数my_memcpy(arr + 5, arr , 5 * sizeof(int));int i = 0;for (i = 0; i < 10; i++){printf("%d ", arr[i]);}return 0;
}
3 memset()函数的基本信息及功能
memset()函数 是⽤来设置内存的,将内存中的值以字节为单位设置成想要的内容。
我们从cplusplus官网(cplusplus(C语言函数查询网站)上我们不难看到memset()函数是有三个参数如图:
(1)void * ptr
调用该函数时,需将待填充内存块的地址作为首个参数传递给ptr指针。由于void *类型指针是一种通用指针,能够接收任意数据类型的地址,因此memset()函数能够以字节为单位,将任意数据类型的内存内容设置为指定值。
(2)int value
(3)size_t num
3.1 memset()函数实战演练
我们下面使用memset()函数进行一个应用,如下:
#include <stdio.h>
#include <string.h>
int main() {char arr[] = "hello world";memset(arr + 2, 'y', 7);printf("%s\n", arr);return 0;
}
该代码将从arr地址偏移2个单位的位置开始,将后续7个元素全部赋值为’y’。
运行结果
3.2 memset()函数能否把整型数组中的元素全部替换为1
目的:想要通过memset()函数将整型数组中的元素全部替换为1
代码如下:
//探讨memset()函数能否把整型数组中的元素全部替换为1
int main() {int arr[5] = { 1, 2, 3, 4, 5 };memset(arr, 1, 20);//以字节为单位设置的int i = 0;for ( i = 0; i < 5; i++){printf("%d ", arr[i]);}return 0;
}
要理解这个问题,首先需要明确数据是以二进制补码形式存储在内存中的。整型数据占用4个字节,即32个比特位。由于正数的原码、反码和补码完全一致,因此我们可以直接得出arr数组中各数字对应的补码表示。
4个二进制数对应一个16进制数,下方为对应的16进制数。
由于内存单元以字节为单位,我们可以通过调试工具直观地观察数据在内存中的存储方式。
由于 memset() 函数以字节为单位对内存进行赋值操作,执行上述代码后,每个字节都将被设置为 1。
内存中:
我们观察到,确实每个字节的内容都被设置成了1
运行结果:
结论:memset()函数无法将整型数组中的所有元素统一设置为1,它仅能将每个字节替换为1。
4 memcmp()函数的基本信息及功能
memcmp()函数比较从ptr1和ptr2指针指向的位置开始,向后的num个字节。
我们从cplusplus官网(cplusplus(C语言函数查询网站)上我们不难看到memcmp()函数是有三个参数如图:
该函数的返回值:
(1)如果 * ptr1(即ptr1指向的数据)小于 * ptr2(即ptr2指向的数据),则返回一个小于0的整数(例如-1)。
(2)如果 * ptr1等于 * ptr2,则返回0。
(3)如果 * ptr1大于 * ptr2,则返回一个大于0的整数(例如1)。
(1)const void * ptr1
ptr1 是一个 const void * 类型的指针,它指向待比较的第一个内存块的起始地址。const 修饰符位于 * 号的左侧,这意味着 ptr1 所指向的内存内容是不可修改的,即通过 ptr1 无法对内存块中的数据进行任何写操作。
(2)const void * ptr2
与ptr1类似,ptr2指向第二个待比较内存块的起始地址。
(3)size_t num
比较 ptr1 和 ptr2 指向的内存区域时,需要向后比较 num 个字节。但在比较过程中,若提前发现大小差异,即可终止比较,否则需完整比较全部 num 个字节。
4.1 memcmp()函数实战演练
4.1.1 memcmp()不提前结束
该情况是memcmp()函数会逐字节比较数据,直到达到指定的num字节数为止。
#include <stdio.h>
#include <string.h>
int main() {int arr1[] = { 1, 2, 3, 4, 5, 6, 7 };int arr2[] = { 1, 2, 3, 4, 5, 8, 8 };int ret = memcmp(arr1, arr2, 20);printf("%d\n", ret);return 0;
}
运行结果
4.1.2 memcmp()提前结束
该情况是memcmp()函数会逐字节比较数据,但是未到达到指定的num字节数为止。这是因为在这之前就发现了大小关系!
#include <stdio.h>
#include <string.h>
int main() {int arr1[] = { 1, 2, 3, 4, 5, 6, 7 };int arr2[] = { 1, 2, 3, 4, 5, 8, 8 }; int ret = memcmp(arr1, arr2, 7 * sizeof(int));printf("%d\n", ret);return 0;
}
运行结果:
以上就是关于内存函数及其部分模拟实现的全部内容,希望能对大家有所帮助或有所启发,感谢各位小伙伴的耐心阅读。咱们下期见!拜拜~
相关文章:
C语言中的内存函数
目录 1 memcpy()函数的基本信息及功能(1) void * destination(2) const void * source(3) size_t num 1.2 memcpy()函数实战演练1.3 memcpy()函数的模拟实现1.3.1 my_memcpy()函数定义及参数1.3.2 my_memcp…...
本特利内华达330103-00-03-05-02-05毫米接近传感器
描述 3300 XL 8 mm近程传感器系统包括:一个3300 XL 8 mm探头、一根3300 XL延长电缆1和一个3300 XL近程传感器2。 该系统提供的输出电压与探针尖端和观察到的导电表面之间的距离成正比,可以测量静态(位置)和动态(振动)值。该系统的主要应用是流体膜轴承机器的振动和位…...
啤酒游戏与系统思考
今天,与上海地产集团的伙伴们一同体验经典的系统思考沙盘模拟——“啤酒游戏”。虽然大家身处房地产行业,但也会惊讶地发现,啤酒游戏的核心理念对任何行业都适用,尤其是站在全局的角度,做出精准决策。 每次进行啤酒游戏…...
id分页遍历数据漏行问题
令入参id为0 while(true){ select * from table where id>#{id} order by id asc limit 100; 取结果集中最大id作为下次查询的入参 其他操作 } 这个算法一般没问题,但在主从数据系统中,主库写,查询从库遍历数据时,出现了…...
【Vue3】Vue3工程的创建 及 开发者工具的安装
目录 一、创建Vue3工程的方式 方法一 方法二 二、区分Vue3 和 Vue2的构建 观察main.js vue3不向下兼容,也就是说Vue3不支持Vue2的写法! JavaScript 的模块导入有两种常见写法: 三、安装Vue3的开发者工具 总结不易~本章节对我有很大的…...
docker exec -it abc bash
当然可以!让我们详细解析一下 docker exec -it abc bash 这个命令的各个部分及其作用。 命令概述 docker exec -it abc bash这个命令用于在已经运行的 Docker 容器 abc 中启动一个新的交互式终端会话。具体来说,它会执行容器内的 bash 命令,…...
基于AI大语言模型的历史文献分析在气候与灾害重建中的技术-以海南岛千年台风序列重建为例
随着人工智能技术的飞速发展,大语言模型如GPT、BERT等在自然语言处理领域取得了显著成果。这些模型不仅提高了文本数据的处理和理解效率,还为历史灾害研究提供了全新的视角和方法。本文将深入探讨基于AI大语言模型的历史文献分析在气候与灾害重建领域中的…...
【最细】自动化测试-解决日志问题,一文贯通...
目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 持续集成的自动化…...
PromptIDE:一款强大的AI提示词优化工具
今天向大家推荐一款专业且免费的AI提示词工具——PromptIDE。作为AI领域从业者,我们都深知提示词质量对模型输出的重要性,而这款工具正是为解决这一痛点而生。 核心功能解析 1、提示词优化 简单输入你的需求描述,点击AI生成提示词…...
f-string 高效的字符串格式化
f-string,称为格式化字符串常量(formatted string literals),是Python3.6新引入的一种字符串格式化方法,该方法源于PEP 498 – Literal String Interpolation,主要目的是使格式化字符串的操作更加简便。 p…...
Powershell及命令行文章合集(不定期更新)
一、Powershell: 1.Powershell中常用命令和常用属性:https://blog.csdn.net/humors221/article/details/147978718 2.Powershell数值应用讲解:https://blog.csdn.net/humors221/article/details/142897029 3.PowerShell 抓取网络日志:https://blog.csdn.net/humors221/artic…...
leetcode hot100刷题日记——8.合并区间
class Solution { public:vector<vector<int>> merge(vector<vector<int>>& intervals) {if(intervals.empty()){//复习empty函数啊,日记1有的return {};}// 按照区间的起始位置进行排序sort(intervals.begin(), intervals.end());vect…...
基于moonshot模型的Dify大语言模型应用开发核心场景
基于moonshot模型的Dify大语言模型应用开发核心场景学习总结 一、Dify环境部署 1.Docker环境部署 这里使用vagrant部署,下载vagrant之后,vagrant up登陆,vagrant ssh,在vagrant 中使用 vagrant centos/7 init 快速创建虚拟机 安装…...
系统设计应优先考虑数据流还是控制流?为什么优先考虑数据流?数据流为主、控制流为辅的架构原则是什么?控制流优先会导致哪些问题?
在当代软件工程的复杂演化中,每个现代系统,不论是处理金融交易的平台、智能家居系统,还是自动驾驶系统,都面临同一个核心问题:设计者该以“数据流”为主导,还是以“控制流”为主导? 在系统设计过程中,工程师所面对的核心问题不仅是代码的堆叠与组织,更是信息流动模式…...
Redis Cluster动态扩容:架构原理与核心机制解析
一、哈希槽的数学本质与拓扑重构 核心图示:哈希槽分配演变 #mermaid-svg-YmcBfipoPA8LvxYF {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-YmcBfipoPA8LvxYF .error-icon{fill:#552222;}#mermaid-svg-Y…...
高考之外,英国国际大一:开启本科留学新征程
在竞争激烈的教育赛道上,高考一直被视为通向高等学府的重要关卡。然而,当千军万马挤在国内升学这座独木桥时,越来越多有远见的学生和家长将目光投向海外,英国本科留学凭借其灵活的录取机制和多元的升学路径,成为众多学…...
UML 图的细分类别及其应用
统一建模语言(UML,Unified Modeling Language)是一种用于软件系统建模的标准化语言,广泛应用于软件工程领域。UML 图分为多种类别,每种图都有其特定的用途和特点。本文将详细介绍 UML 图的细分类别,包括 类…...
Android10如何设置ro.debuggable=1?
说明:仅供学习使用,请勿用于非法用途,若有侵权,请联系博主删除 作者:zhu6201976 目录 一、背景 二、如何解决? 三、操作步骤 一、背景 Android 10 开始的限制:ro.debuggable 是只读属性 从 …...
每日算法刷题计划Day12 5.21:leetcode不定长滑动窗口求最短/最长3道题,,用时1h40min(有点长了)
求最短/最小 一般题目都有「至少」的要求。 想窗口成立的条件,right右移增强条件,然后while循环left右移最终破坏条件 模版套路 在while循环内更新答案 class Solution { public:int minSubArrayLen(int target, vector<int>& nums) {int …...
JUC高并发编程
1. JUC概述 1.1 什么是JUC JUC时java.util.concurrent工具包的简称。这是一个处理线程的工具包,JDK1.5开始出现的。 1.2 进程和线程的概念 1.2.1 进程与线程 打开一个软件,就开启了一个进程,一个进程会包括很多个线程,线程是…...
算法--js--电话号码的字母组合
题:给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。 function letterCombinations (digits){if (!digits.length)…...
数据库blog4_数据库软件的设计方法与实际架构
🌿数据库的设计 由上一章可以得出数据库着重关注数据的逻辑结构和存储结构。即这是数据库设计的核心,但详细的设计结构也要研究。以下是介绍 🍂数据库架构思路 ● 数据库本身 数据(Data) 数据:数据库中存储的实际信息,是用户存储…...
Kubernetes中runnable接口的深度解析与应用
在 Kubernetes 或其他 Go 项目中,runnable 接口定义了一个通用的运行契约,允许不同类型的组件通过统一的接口启动和管理生命周期。以下是详细解析: 1. 接口定义分析 type runnable interface {RunWithContext(ctx context.Context) error }关…...
curl: (35) Peer reports incompatible or unsupported protocol version.
这个错误信息表明在使用 curl 命令时遇到了 TLS 协议版本不兼容的问题。这通常是因为 curl 和服务器之间在协商 TLS 协议版本时出现了问题。在 CentOS 7 中,你可以尝试以下解决方案: 一、使用--tlsv1.2选项 尝试在 curl 命令中添加 --tlsv1.2 选项&…...
算法竞赛板子
算法竞赛板子 目录 1. ST表_区间最值_gcd_按位与_按位或 2. 树状数组 3. 快读 4. 带权并查集 5. 欧拉筛 6. 组合数 7. lucas定理求组合数 8. 离散化 9. 线形基 10. 主席树 11. 约瑟夫环 12. tarjan 求静态LCA 13. tarjan 求无向图割点 14. tarjan 求无向图割点后的连通块 15.…...
Vulkan 动态渲染
前言 开发环境:Vulkan 1.3.2 Vulkan SDK VS 2022。语言 C vulkan.hpp。依赖vk-bootstrap,SDL3。 很久以前学Vulkan学得不彻底,写引擎的时候才发现那么困难,于是重新回来巩固一下Vulkan基础。并发现了很多小细节大学问。 动态渲…...
【亲测有效】Ubuntu22.04安装黑屏重启进入系统卡死
一:进入U盘安装引导时黑屏 问题描述:选择 ‘try or install ubuntu’ ,开始安装,出现黑屏。 解决方案: 1.安装时,先选择" try or install ubuntu", 此时不要按enter,按"e&quo…...
wps编辑技巧
1、编辑模式 2、图片提取方法:右键保存图片 可以直接右键保存下来看看是否是原始图,如果歪着的图,可能保存下来是正的,直接保存试下 3、加批注...
磁盘分区与挂载——笔记
1.磁盘分区 磁盘分区是将物理磁盘划分为多个逻辑区域的过程。每个分区可视为独立的存储单元,拥有独立的文件系统,可安装不同操作系统或存放不同类型数据。例如,将硬盘分为系统盘(存放操作系统)、数据盘(存…...
安卓基础(代码解析)
Build.VERSION.SDK_INT > Build.VERSION_CODES.M && !Settings.canDrawOverlays(this) Build.VERSION.SDK_INT > Build.VERSION_CODES.M Build.VERSION.SDK_INT:获取当前Android系统的API版本号,每个Android版本都有一个对应的API版本号…...
基于Android的XX校园交流APP
开发语言:Java框架:ssmAndroidJDK版本:JDK1.8服务器:tomcat7数据库:mysql 5.7数据库工具:Navicat12开发软件:eclipse/myeclipse/ideaMaven包:Maven3.3.9 系统展示 APP登录 APP首页…...
tshark的使用技巧(wireshark的命令行,类似tcpdump):转换格式,设置filter
tshark的使用技巧(wireshark的命令行,类似tcpdump):转换格式,设置filter tshark一般在 C:\Program Files\Wireshark 使用管理员权限 打开cmd tshark -D 列出支持抓包的接口: c:\Program Files\Wiresh…...
TCP全连接和tcpdump抓包实现
1.全连接队列 listen函数的第二个参数backlog1,就是TCP全连接队列的长度。 客服端进行连接进入established状态后,服务器如果处于忙碌状态没有调用accept函数将连接取走,这个连接就会呆在TCP全连接队列中,直到上层调用函数accep…...
Windows安装Jenkins Jenkins打包部署
1、 start.cmd echo off title jenkins SET JENKINS_HOMED:\tools\Jenkins\home SET JAVA_HOMED:\developtools\jdk-11.0.8 D:\developtools\jdk-11.0.8\bin\java.exe -jar D:\tools\Jenkins\jenkins.war --httpPort8089 pause执行start.cmd 报错:是因为原来jdk8…...
目标检测:YOLO 模型详解
目录 一、YOLO(You Only Look Once)模型讲解 YOLOv1 YOLOv2 (YOLO9000) YOLOv3 YOLOv4 YOLOv5 YOLOv6 YOLOv7 YOLOv8 YOLOv9 YOLOv10 YOLOv11 YOLOv12 其他变体:PP-YOLO 二、YOLO 模型的 Backbone:Focus 结构 三、…...
85本适合AI入门的人工智能书籍合集免费资源
宝藏资源!分享85本适合AI初学者入门人工智能的书籍合集给大家下载,都是epub格式的,方便大家阅读,文末给大家提供免费下载方式,主要包括如下电子书: Julia机器学习核心编程:人人可用的高性能科学…...
Zabbix开源监控的全面详解!
一、zabbix的基本概述 zabbix,这款企业级监控软件,能全方位监控各类网络参数,确保企业服务架构的安全稳定运行。它提供了灵活多样的告警机制,帮助运维人员迅速发现并解决问题。此外,zabbix还具备分布式监控功能&#…...
[杂学笔记]浏览器多进程与多线程架构、wstring类型、哈希表、红黑树与哈希表的对比、C++标准库Random类
目录 1. 浏览器多进程与多线程架构 2. wstring类型 3. 哈希表 4. 红黑树与哈希表的对比 5. C标准库Random类 1. 浏览器多进程与多线程架构 现代的浏览器(如Chrome)采用的是多进程与多线程结合的架构设计的。 多进程机制:Browser主进程用…...
AI+MCP 自动发布小红书笔记
分享一个超赞的效率工具—小红书MCP发布器(xhs-mcp-server),让你轻松实现AI内容一键发布到小红书! Cursor配置 在 Cursor 的 Cursor Settings 中找到 MCP,点击右侧上方的 Add new global MCP server 按钮,…...
02_redis分布式锁原理
文章目录 一、redis如何实现分布式锁1. 使用 SETNX 命令2. 设置过期时间3. 释放锁4. 注意事项5. 示例代码 二、Java中分布式锁如何设置超时时间1. Redis分布式锁2. 基于Zookeeper的分布式锁3. 基于数据库的分布式锁注意事项 一、redis如何实现分布式锁 Redis 实现分布式锁是一…...
07SpringMVC底层形象解析
目录 一、基于餐厅比喻的代码示例 ,帮助你理解各组件间的协作关系 1. DispatcherServlet 配置(服务员) 2. HandlerMapping 配置(菜单索引) 3. Controller 实现(厨师) 4. Service 层&#x…...
jvm调优以及常见jvm问题解决等
1、通过top命令查询异常的进程 top 2、通过 使用top -Hp<PID>命令查看该进程内各个线程的CPU占用情况: top -Hp PID 记录下占用CPU较高的线程ID。 3、转换线程ID为十六进制 使用printf命令将线程ID 19664 转换为十六进制,结果为 0x4cd0࿱…...
深入理解万维网:URL、HTTP与HTML
深入理解万维网:URL、HTTP与HTML 统一资源定位符(URL) 1.1 什么是URL? 统一资源定位符URL(Uniform Resource Locator)是万维网上用于标识和定位各种文档的标准方法,它使每个资源在互联网范围内…...
RPC 协议详解、案例分析与应用场景
一、RPC 协议原理详解 RPC 协议的核心目标是让开发者像调用本地函数一样调用远程服务,其实现过程涉及多个关键组件与流程。 (一)核心组件 客户端(Client):发起远程过程调用的一方,它并不关心调…...
唯创安全优化纸业车间安全环境:门口盲区预警报警器的应用与成效
一、客户现场 客户主要从事于卷烟纸、成型纸、烟草制造业用纸及其他特定用途纸类制品的加工、生产与销售。在其厂区内,叉车频繁作业,车间环境复杂。经实地查看,发现几大安全隐患: 门口拐角隐患:门口拐角处因卷帘门阻…...
解决dedecms织梦系统{dede:arclist keyword=‘动态获取关键词‘}只生效一次
当我们通过{dede:arclist keyword关键词}来调用文章列表时,你会发现只在其中一个栏目里生效,在其他栏目,仍然显示上一次的关键词。 原因是由于arclist的缓存导致的。 只需修改/include/taglib/arclist.lib.php文件,大概在384行&a…...
高级学习算法(神经网络 决策树)
目录 神经网络 (Neural networks)神经网络的介绍需求预测 (Demand Prediction)例子:图像识别人脸识别(Face recognition)汽车分类(Car classification) 神经网络中的层更复杂的神经网络推理:前向传播 (Forw…...
labview硬件部分——温度测量
硬件连接: (1)温度测量的电压采集:(电压的单位为V) 温度采集程序图: 运行结果: 我们可以在显示控件中,看到温度采集的电压值 (2)温度采集的电压…...
labview——控制继电器模块
高电平——5V 超过一定的电压值,LED打开、继电器打开。(结合模拟电压采集与LED控制) 控制继电器是数字信号控制。程序与LED控制一致。 (1)我们先来看看继电器的控制 使用布尔按键,按键按下时࿰…...
ArcGIS Pro 3.4 二次开发 - 核心主机
环境:ArcGIS Pro SDK 3.4 .NET 8 文章目录 核心主机1 核心主机1.1 初始化核心主机 核心主机 1 核心主机 1.1 初始化核心主机 using ArcGIS.Core.Data; //必须引用 ArcGIS.CoreHost.dll using ArcGIS.Core.Hosting; class Program { //应用程序入口点必须包含 [S…...