C语言-详解内存函数

文章目录
- 1.memcpy使用和模拟实现
- 1.1 memcpy函数的使用规则
- 1.2 memcpy函数的使用
- 1.2 模拟实现memcpy函数
- 2.memmove 函数的使用和模拟实现
- 2.1 memmove 函数使用规则
- 2.2 memmove函数的使用
- 2.3 模拟实现memmove函数
- 2.3.1 从后往前移
- 2.3.2 从前往后移
- 2.4 算法实现
- 2.4.1 从前往后移算法实现
- 2.4.2 从后往前移的算法实现
- 2.4.3 最终代码展示及效果
- 3.memset 函数的使用
- 3.1 memset 函数的使用规则
- 3.2 memset函数的使用
- 3.3 使用memset函数需要注意的地方
- 4.memcmp 函数的使用
- 4.1 memcpy 函数的使用规则
- 4.2 memcmp函数的使用
- 5.总结
1.memcpy使用和模拟实现
1.1 memcpy函数的使用规则
它的函数原型如下:
void * memcpy ( void * destination, const void * source, size_t num );
具体的函数介绍如下:

好,相信同学们看了这个函数,应该是能够简单了解函数中各个参数的用法。
下面我们来总结一下:
- 函数
memcpy从source的位置开始向后复制num个字节的数据到destination指向的内存位置。- 这个函数在遇到
'\0'的时候并不会停下来。- 如果
source和destintation有任何的重叠,复制的结果都是未定义的。
1.2 memcpy函数的使用
好,当我们讲了memcpy函数使用规则后,来看一下memcpy函数该怎么使用吧~

代码如下:
#include <stdio.h>
#include <string.h>
int main() {int arr[] = { 1,2,3,4,5,6,7,8,9,10 };int arr2[20] = { 0 };memcpy(arr2, arr,20);//这里的arr2是目标位置,arr是起始位置,20指的是复制的字节个数,int类型占4个字节, 那这里的20就相当于5个int类型的元素。//也就是说将arr数组中5个元素拷到arr2数组中,arr2是数组首元素的地址,也就是说当执行完这个语句,arr2数组前5个元素存的是arr1数组前5个元素的值for (int i = 0; i < sizeof(arr2) / sizeof(arr2[0]); i++)//sizeof(arr2)/sizeof(arr2[0]),本质上就是用arr2数组所占的总大小/arr2数组中一个元素所占的大小,得出的是arr2它数组元素个数{printf("%d ", arr2[i]);}return 0;
}
代码分析: 这里我们用
mencpy函数主要是将arr1数组中前5个元素拷到arr2起始地址处。
也就是说这里用memcpy函数进行拷贝的话,到时会将arr2数组中前5个元素给覆盖掉。
如图:
相信同学们看了这个图以及上面的代码注释,是能够理解那个代码逻辑的。
VS运行效果:
通过观察: 我们发现运行结果确实是符合我们预期的,跟我们分析得是一模一样的。

1.2 模拟实现memcpy函数
好,刚刚我们讲了memcpy函数的使用,那如何模拟实现一个memcpy函数呢?
这里想必同学们有点无从下手,没事,博主这里画个图,说不定大家很快就明白了~
如图:

从图中: 假设我们想要把arr中前5个元素拷到arr2数组中第7到第11个元素的位置,我们该怎么做呢?
在讲解这个之前,我们先看一下int类型和char类型在VS编译器中各占几个字节?
如图:

从运行结果来看: 我们可以看出int是占4个字节,char是占1个字节。
有同学可能要问了,知道这个有什么用呢?
如图:

从图中: 我们看出memcpy第三个参数就是所要拷贝的字节个数,这时我们之前讲的int和char所占的大小就发挥作用了。
因为我们到时要在模拟实现的my_memcpy函数内部中,要把数组中int*的元素强转为char*的元素,通过所要传的字节数,用一个while循环,对里面的字节数进行交换。
这里想必同学们会有疑问?为什么要转换为char*的元素进行交换,而不转换为其他类型的元素进行字节数的交换呢?
这是因为: char*类型每解引用一次,访问的是一个字节的内存空间。
如果说我们把目标地址dst和起始地址src转换为其他类型。如:short*或int*,那么在进行字节的拷贝时可能会跳过一些字节,这会导致拷贝结果不正确。
因此我们要将它强制转换为char*,这样就可以保证我们可以正确地访问和拷贝内存中的每个字节。
好,当我们分析成这样,我们也能画个图把它的思路给分析出来~
如下:

好,同学们可以看一下博主总结的思路,自己尝试动手写一下这个模拟实现memcpy函数的代码出来。
如果真的写不出来,也没关系,看一下博主是怎么写这个代码的,模仿一下博主的写法。
代码如下:
#include <stdio.h>
#include <assert.h>void* my_memcpy(void* px, void* py, size_t count)//px是指向目标地址,而py指针指向源地址,这里的count可以理解为交换的字节数有多少
{assert(px && py);//用asser判断px和py指针是否为空void* ret = px;//这里用指针变量接收px目标位置的地址while (count--)//通过所要交换的字节数,从而确立循环的次数{*(char*)px = *(char*)py;//将源地址py指向的字节值赋给目标地址px 指向的字节(char*)px = (char*)px + 1;//px 指针向后移动一个字节(char*)py=(char*)py+1;//py 指针向后移动一个字节}return ret;//将指针变量ret的地址返回去
}int main() {int arr[] = {10,9,8,7,6,5,4,3,2,1 };int arr2[20] = { 0 };//针对内存块进行拷贝my_memcpy(arr2+6, arr, 5 * sizeof(int));//这里的arr2+6是目标位置,也就是说跳过6个元素。arr是源位置, 5 * sizeof(int)指的是5个数组元素for (int j = 0; j < sizeof(arr2) / sizeof(arr2[0]); j++)//本质上就是用arr2数组所占的总大小/arr2数组中一个元素所占的大小,得出的是arr2它数组元素个数{printf("%d ", arr2[j]);}printf("\n");return 0;
}
好,相信同学们看了这个代码以及注释,是能够理解这个代码逻辑的。

VS运行效果:

从运行结果来看: 我们发现
VS编译器的运行结果是符合我们的预期的,也就是说它把arr2数组中的第七个~第十一个元素全都替换为arr数组中前五个元素。
好,这个memcpy函数我们就讲到这里,希望同学们可以理解,同学们要多多实践才行哦~
2.memmove 函数的使用和模拟实现
2.1 memmove 函数使用规则
它的函数原型如下:
void * memmove ( void * destination, const void * source, size_t num );
具体的函数介绍如下:

我们这里就做一个小小地总结吧:
memmove函数和memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的。- 如果源空间和目标空间出现重叠,就得使用
memmove函数。
2.2 memmove函数的使用
我们这里直接上代码吧~
代码如下:
#include <stdio.h>
#include <string.h>
int main() {int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };memmove(arr1 + 2, arr1, 5 * sizeof(int));//目标地址是arr1跳过两个元素的位置,起始地址是arr1首元素的地址,5*sizeof(int)指的是5个整型数组中的元素for (int i = 0; i < sizeof(arr1) / sizeof(arr1[0]); i++)//这里本质上就是用arr1数组所占的总大小/arr1数组中一个元素所占的大小,得出的是arr1它数组元素个数 {printf("%d ", arr1[i]);}printf("\n");return 0;
}
VS运行效果:
通过运行结果:我们可以看出VS的运行结果是符合我们预期的。
我们这里也简单地给大家画了一个图
如下:
从图中: 我们把蓝色框住的部分替换为1-5的数值,那有同学可能会问了?
这个memmove函数具体是怎么移动的,它是怎么做到不覆盖其他元素呢?
别急,等下博主讲memmove函数模拟实现的时候还会给你细细道来。
2.3 模拟实现memmove函数
好,接下来给大家详细讲一下模拟memmove函数的思路~
2.3.1 从后往前移
首先,还是老样子,我们这里要将目标地址后的5个元素替换为源地址后的5个元素。
如下图:

那我们该怎么移红色框住的5个元素到蓝色框住的区域中呢?还要避免源字符串src中的5个元素被覆盖。
具体操作如下动图所示:

从动图中: 大家有没有发现,这里我们采取的是从后往前的方法来移动的。
这里我们是先将数组为5的元素移到数组7的位置中,再把数组为4的元素移到数组6的位置中,以此类推……
这样子移的目的是避免起始地址src的元素被覆盖,如果我们先将数组元素为1移到3的位置中,可能把元素为3的数字给覆盖掉,这显然是不合理的。因为memmove函数是允许源空间和目标空间出现重叠的。
2.3.2 从前往后移
还是老样子,我们这里要将目标地址后的5个元素替换为源地址后的5个元素。
如下:

但是这里大家有没有发现,这里的起始地址src是高过目标地址dest的,因此我们就不能用刚刚的从后往前的方法来移动元素。
我们这里是采用从前往后的方法来移动元素。
具体操作流程如下:


从动图中: 我们这里是采用从前往后的方法来移动元素。
同理:我们这样子移动的目的也是为了避免起始地址中数组元素为6和7在移动过程中被覆盖掉。
2.4 算法实现
好,前面我们讲了模拟实现memmmove函数两种移动方法,分别是从前往后移和从后往前移的方法。
那具体该如何实现这两种方法的算法呢?下面来看一下。
2.4.1 从前往后移算法实现
这里的从前往后移的算法其实跟我们刚刚写的模拟实现memcpy函数的思路其实是差不多的。
为什么这么说呢?我们来看一下下面这幅图:

通过此图: 我们发现memmove函数中的第三个参数是size_t,也就是字节个数。
那我们知道参数num的值,那就好办了,我们这里可以分别把src指针和dest转换为char*类型的指针,对其解引用,每解引用一次,两个指针各自向后偏移一个元素,然后根据参数num的个数,来决定所要交换字节的次数。
需要注意的是: 这里面我们还要了解一个知识~
也就是对于相同类型的数组,数组元素的地址是按照下标递增的。下标的值越高,数组元素的地址就越高。
那同学们可能会有疑问:直到这个东西有什么用呢?
这是因为我们要在模拟实现memmove函数中,加上个if的判断条件,这里面就是用来判断什么情况下用从前往后移,什么情况下用从后往前移。
那显然: 我们这里的起始地址src是打过目标地址dest的。因此那个代码我们就可以这么写~
代码如下:
if (dest < src)//从前往后移的代码逻辑{while (nums--) {*(char*)dest = *(char*)src;(char*)dest = (char*)dest + 1;(char*)src = (char*)src + 1;}}else {;//从后往前移的代码逻辑}
2.4.2 从后往前移的算法实现
那么同理:我们看一下从后往前移的算法该怎么实现。
如下:

同样地,我们这里还是先观察memmmove的字节个数num,这个是关系到我们要交换多少个字节个数。
那么细心的同学可能发现: src指向的是数组首元素的地址,也就是1的地址。而dest指向的是数组第三个元素,也就是3的地址。
那么我们之前就讲过: 要先把起始地址中最后那个元素的字节数与目标地址最后那个元素的字节数进行交换,然后每交换一个字节数,那个字节数num的值就会-1,直到num的值为0,才会停止交换字节数。这样子才不至于说移动的过程中把起始地址中的元素给覆盖掉。
相信同学们看到这里,应该是能够把这个代码给写出来的,大家可以尝试动手写一下~
好,如果同学们写完的话,可以看一下自己写的代码和博主写的代码逻辑是否相同~
代码如下:
if (dest < src)//从前往后移的代码逻辑
{while (nums--) {*(char*)dest = *(char*)src;(char*)dest = (char*)dest + 1;(char*)src = (char*)src + 1;}
}
else {;//从后往前移的代码逻辑while (nums--)//每交换一次字节数,nums的值都会递减;{*((char*)dest + nums) = ((char*)src + nums);}
}
2.4.3 最终代码展示及效果
代码实现:
#include <stdio.h>
#include <assert.h>
void* my_memmove(void* dest, void* src, int nums) {assert(dest && src);void* ret = dest;if (dest < src)//从前往后移的代码逻辑{while (nums--) {*(char*)dest = *(char*)src;(char*)dest = (char*)dest + 1;(char*)src = (char*)src + 1;}}else {;//从后往前移的代码逻辑while (nums--)//每交换一次字节数,nums的值都会递减;{*((char*)dest + nums) = *((char*)src + nums);}}return ret;
}int main() {int arr[] = { 1,2,3,4,5,6,7,8,9,10 };my_memmove(arr+2, arr, 5 * sizeof(int));//起始地址为数组首元素地址,目标地址为数组首元素跳过两个元素的地址,交换的是5个int类型的元素,也就是20个字节的空间for (int i = 0; i < 10; i++) {printf("%d ", arr[i]);}printf("\n");return 0;
}
这里面我们分别演示
VS从前往后移和从后往前移的运行效果吧~
1.从前往后移运行效果:
从此图: 可以看出起始地址src是高过目标地址dest,所以这里是把目标地址中的3~5的元素替换为起始地址中的6-8元素。说明是能够达到我们的预期效果的。
2.从前往后移运行效果:
从此图: 可以看出目标地址dest是高过起始地址src,所以这里本质上是将目标地址的3~5的元素替换为起始地址中的1~3的元素,说明这也是达到我们想要的预期效果。
好,这个memmove函数我们就讲到这里,这个函数相对比较复杂,下来同学们要多去实践这个代码。
3.memset 函数的使用
3.1 memset 函数的使用规则
它的函数原型如下:
void *memset (void *ptr,int value,size_t num)
具体的函数介绍如下:

这里相信同学们看了函数官网的介绍,应该是能够理解memset函数的规则,我们这里就浅浅总结一下吧~
总结: memset函数是用来设置内存的,将内存中的值以字节为单位设置成想要的内容
3.2 memset函数的使用
代码如下:
#include <stdio.h>
#include <string.h>
int main() {char arr[] = "she is my sister!!!";//这里面创建了一个字符数组,里面的字符各占一个字节memset(arr, 'x', 3);//第一个参数是目标地址,第二个参数为填充的内存块,第三个参数为字节数,由于这里第三个字节数为3,因此会把前三个字符元素she替换为'x'printf("%s\n", arr);//这里从数组中的首元素地址开始往后打印字符串,直到遇到\0才停止打印return 0;
}
相信同学们看了这个代码的注释,自己是应该知道怎么使用这个memset函数的。
VS运行效果:
从图中: 可以看出VS的运行结果是符合我们的预期的。
3.3 使用memset函数需要注意的地方
这里有同学可能会误用memset函数,比如他们可能会把代码写成这样:,运行时出现这种情况
如下:

他们会有所好奇“为什么打印的不是整数1,而是这么大的数呢?”
别急,这里博主给你讲一下它的原理,相信你们很快就懂了~
如图:

我们通过在vs编译器调试时发现,arr数组中的5个元素全都设置都是以01 01 01 01存储的。
这是因为memset函数是以字节单位来设置的,它是把每个字节都填充为1,而不是说它把一个元素填充为1,
我们从vs内存看出它是以十六进制来存储的,因此把这四个01构成一个整数,它就是这么一个值。
具体计算过程如下:

但是memset函数是可以为任何任意一个数据类型设置内存块来填充的。
那么博主这么讲: 就是想告诉同学们,memset函数是以字节为单位设置的,它会把每个字节填充为memset函数第二个参数那个内存块。所以我们可不敢随意用memset函数把每个元素设置,这是做不到的。
好,相信讲到这里,同学们已经知道memset函数怎么用了,那这个memset函数我们就讲到这里!
4.memcmp 函数的使用
4.1 memcpy 函数的使用规则
它的函数原型如下:
int memcmp ( const void * ptr1, const void * ptr2, size_t num );
具体的函数介绍如下:

相信同学们看了这个函数官网的介绍,应该是知道这个memcmp函数的使用规则的,那我们这里就简单总结一下吧~
- 比较从
ptr1和ptr2指针指向的位置开始,向后的num个字节。memcmp函数按照字节顺序比较两个内存块中的字节,并返回一个整数值来表示比较结果。
具体规则如下:
- 如果
ptr1的对应字节小于ptr2的对应字节,则返回一个负数。- 如果
ptr1的对应字节等于ptr2的对应字节,则返回0。- 如果
ptr1的对应字节大于ptr2的对应字节,则返回一个正数。通俗点来讲: 在比较字符串时,ASCII 码值就是内存块中对应字符的值。因此,可以说
memcmp函数实际上是通过比较两个字符串的ASCII码值来判断它们的大小关系。
4.2 memcmp函数的使用
我们这里就简单演示一下memcmp函数用法是怎么样,相信同学们看了博主写的这个代码,应该是可以上手的~
代码如下:
#include <stdio.h>
#include <string.h>
int main()
{char buffer1[] = "DWgaOtP12df0";//创建两个字符数组buffer1和buffer2char buffer2[] = "DWGAOTP12DF0";int n = memcmp(buffer1, buffer2, sizeof(buffer1));//比较两个字符串相应字符的Ascll码值。由于buffer1第三个字符的Ascll码值大于buffer2第三个字符的Ascll码值,因此这里返回一个大于0的数字,无需往后比较字符。if (n > 0)//因为buffer1>buffer2,所以会执行这条语句printf("'%s' is greater than '%s'.\n", buffer1, buffer2);//%s是从数组首元素开始往后打印字符串,直到遇到'\0'为止else if (n < 0)printf("'%s' is less than '%s'.\n", buffer1, buffer2);elseprintf("'%s' is the same as '%s'.\n", buffer1, buffer2);return 0;
}
这个函数跟我们之前讲的strcmp函数非常类似,都是比较两个字符数组相应字符的Ascll码值,如果出现对应字符的Ascll码值不相同,无需往后进行比较。
相信同学们看了博主写的代码注释,是可以理解这个代码的。
VS运行效果:
分析: 由于buffer1数组第三个字符的Ascll码值大于buffer2第三个字符的Ascll码值,因此返回的是大于0的数。因此执行的是if(n>0)的那条语句。那么从VS运行结果来看,它是达到我们的预期效果的。
好,这个memcmp函数我们就讲到这里,希望同学们可以理解!
5.总结
好,讲了这么多,让我们来回顾今天讲了什么吧~
- 函数
memcpy主要功能是从起始位置src复制nums个字节的数据到dest指向的内存位置。
但是这个函数遇到'\0'的时候,并不会停下来的。
如图:
分析: 这里我们是把arr2数组中的10字节的元素用memcpy函数拷到arr数组中,那从这个运行结果,我们可以看出这个arr数组已经是越界访问了。因此使用这个memcpy函数要小心一点才行。
如果起始地址src和目标地址dest有任何的重叠,复制的结果都是未定义的。memmove函数和memcpy函数的功能基本相同,也是遇到'\0'的时候,并不会停下来的。
唯一不同的是memmove函数处理的源内存和目标内存块是可以重叠的。
如果说源空间srt和目标空间dest出现重叠,就得使用memmove函数来处理。memset函数是用来设置内存的,将内存的值以字节设置成想要的内容。
需要注意的是:memset函数是以字节单位来设置的,所以各位同学们要合理使用memset函数,否则运行时会输出一个让人意想不到的结果嘿嘿!memcmp函数是比较两个字符数组元素对应的Ascll码值,从数组首元素开始往后比较,比较nums个字节。如果出现对应字符的Ascll码值不相同,无需往后进行比较。
好,讲到这里,相信同学们对C语言的内存函数有了基本的理解,大家看完这篇博客,自己下来要多去实践四个函数。唯有这样大家才能把编程学好的!
**当然如果大家如果觉得博主这篇文章对你学习C语言有帮助的话,可以给博主一键三连吗 **

** 谢谢大家支持!!! **
相关文章:
C语言-详解内存函数
文章目录 1.memcpy使用和模拟实现1.1 memcpy函数的使用规则1.2 memcpy函数的使用1.2 模拟实现memcpy函数 2.memmove 函数的使用和模拟实现2.1 memmove 函数使用规则2.2 memmove函数的使用2.3 模拟实现memmove函数2.3.1 从后往前移2.3.2 从前往后移 2.4 算法实现2.4.1 从前往后移…...
【核心完整复现】基于目标级联法的微网群多主体分布式优化调度
1 主要内容 之前发布了华电学报的复现程序《基于目标级联法的微网群多主体分布式优化调度》,具体链接为【防骗版】基于目标级联法的微网群多主体分布式优化调度,虽然对模型及结果进行了复现,但是部分模型细节和参数并没有完全实现࿰…...
Mac下安装NVM,NVM安装Node(附带NPM)
1、理解NVM、node、NPM 什么是NVM? NVM: Node.js Version Manager,用来管理 node 的版本。 什么是 Node.js? Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境。 Node.js使用了一个事件驱动、非阻塞式I/O的模型( Node.js的特性&…...
java之变量的作用域
在java中,变量需要像其他编程语言中先定义,再使用。但并不是定义好就能用。需要对变量定义一个作用范围才能使用,这个作用范围称为作用域。 在java程序中,变量会定义在一个花括号内,花括号内的区域就是作用域。 比如…...
CentOS 7软件安装全攻略:YUM命令详解与实战
在CentOS 7中,软件安装主要依赖于其强大的包管理器——YUM(Yellowdog Updater Modified)。YUM可以自动解决软件包之间的依赖关系,使得软件的安装、更新和卸载变得简单而高效。本文将详细介绍CentOS 7中软件安装的相关命令、选项和…...
达梦关键字(如:XML,EXCHANGE,DOMAIN,link等)配置忽略
背景:在使用达梦数据库时,查询SQL中涉及XML,EXCHANGE,DOMAIN,link字段,在达梦中是关键字,SQL报关键词不能使用的错误。 解决办法: 配置达梦安装文件E:\MyJava\dmdbms\data\DAMENG\dm.ini 忽略这些关键词,…...
2024/4/11 直流电机调速/PWM
一、直流电机简介和PWM原理 直流电机是一种将电能转换为机械能的装置。一般的直流电机有两个电极,当电极正接时,电机正转,当电极反接时,电机反转 直流电机主要由永磁体(定子)、线圈(转子&…...
贝乐虎儿歌v6.8.0解锁高级版亲子学习儿歌
软件介绍 贝乐虎儿歌免费版app,出自乐擎网络的创意工坊,专为孩子们雕琢了一系列富含创意的动画儿歌内容。这款app通过贝乐虎兄弟的可爱形象,让孩子们在愉快的观看中接触到各种儿歌和故事。不仅如此,app还巧妙地将古诗、英语等学习…...
计算机网络技术-RIP、0SPF和BGP协议的工作原理和应用
目录 RIP (Routing Information Protocolv)路由信息协议OSPF(Open Shortest Path First) 开放式最短路径优先BGP( Border Gateway Protocol)边界网关协议 RIP (Routing Information Protocolv)路由信息协议 RIP协议 是 TCP/IP环境中开发的第一个路由选择…...
机器学习——自动驾驶
本章我们主要学习以下内容: 阅读自动驾驶论文采集数据根据论文搭建自动驾驶神经网络训练模型在仿真环境中进行自动驾驶 论文介绍 本文参考自2016年英伟达发表的论文《End to End Learning for Self-Driving Cars》 📎end2end.pdf...
Android 14 vold 分析(2)VolumeManager 和 NetlinkManger
3. VolumeManager::Instance() 和 VolumeManager::start() system/vold/VolumeManager.cpp 3.1 Instance()没啥好说的 非常简单 112 VolumeManager* VolumeManager::Instance() {113 if (!sInstance) sInstance new VolumeManager();114 return sInst…...
《黑马点评》Redis高并发项目实战笔记(上)P1~P45
P1 Redis企业实战课程介绍 P2 短信登录 导入黑马点评项目 首先在数据库连接下新建一个数据库hmdp,然后右键hmdp下的表,选择运行SQL文件,然后指定运行文件hmdp.sql即可(建议MySQL的版本在5.7及以上): 下面这…...
pytorch车牌识别
目录 使用pytorch库中CNN模型进行图像识别收集数据集定义CNN模型卷积层池化层全连接层 CNN模型代码使用模型 使用pytorch库中CNN模型进行图像识别 收集数据集 可以去找开源的数据集或者自己手做一个 最终整合成 类别分类的图片文件 定义CNN模型 卷积层 功能:提…...
【C++入门】内联函数、auto与基于范围的for循环
💞💞 前言 hello hello~ ,这里是大耳朵土土垚~💖💖 ,欢迎大家点赞🥳🥳关注💥💥收藏🌹🌹🌹 💥个人主页&#x…...
服务器停用,备份服务文件。
文章目录 引言I 文件备份1.1 数据库文件/证书1.2 redis1.3 nacosII JAVA流水线备份2.1 java构建2.2 镜像构建2.3 docker 部署2.4 子模块构建2.5 Dockerfile_prodIII VUE项目流水线备份3.1 Node.js 构建3.2 Dockerfile_prod...
基于Python的深度学习的中文情感分析系统(V2.0),附源码
博主介绍:✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专栏推荐订阅👇…...
使用Postman发送跨域请求实验
使用Postman发送跨域请求 1 跨域是什么?2 何为同源呢?3 跨域请求是如何被检测到的?4 Postman跨域请求测试4.1 后端准备4.2 测试用例4.2.1 后端未配置跨域请求(1) 前端不跨域(2)前端跨域 4.2.2 后端配置跨域信息(1&…...
4、jvm-垃圾收集算法与垃圾收集器
垃圾收集算法 分代收集理论 当前虚拟机的垃圾收集都采用分代收集算法,这种算法没有什么新的思想,只是根据对象存活周期的不同将内存分为几块。一般将java堆分为新生代和老年代,这样我们就可以根据各个年代的特点选择合适的垃圾收集算法。 比如…...
[Excel]如何限制儲存格輸入格式? 以“字首為英文字母大寫,其餘為數字,共15碼“為範例
[Excel]如何限制儲存格輸入格式 需求: 當一個excel表格需要由多位使用者來輸入資料時,難免會出現資料輸入錯誤問題,尤其是料號,品號或是訂單號的長類型編碼。若是問題屬於輸入錯誤"資料"但格式未錯誤,則可能需要讓exce…...
错题记录-华为海思
华为 海思数字芯片 参考 :FPGA开发/数字IC笔试系列(5) 华为海思IC笔试解析 FPGA开发/数字IC笔试系列(6) 华为海思IC笔试解析 SystemVerilog Function与Task的区别 $readmemh与$readmemb这两个系统任务是用来从指定文件中读取数据到寄存器数组或者RAM、ROM中。除了…...
接口测试中缓存处理策略
在接口测试中,缓存处理策略是一个关键环节,直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性,避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明: 一、缓存处理的核…...
在四层代理中还原真实客户端ngx_stream_realip_module
一、模块原理与价值 PROXY Protocol 回溯 第三方负载均衡(如 HAProxy、AWS NLB、阿里 SLB)发起上游连接时,将真实客户端 IP/Port 写入 PROXY Protocol v1/v2 头。Stream 层接收到头部后,ngx_stream_realip_module 从中提取原始信息…...
Pinocchio 库详解及其在足式机器人上的应用
Pinocchio 库详解及其在足式机器人上的应用 Pinocchio (Pinocchio is not only a nose) 是一个开源的 C 库,专门用于快速计算机器人模型的正向运动学、逆向运动学、雅可比矩阵、动力学和动力学导数。它主要关注效率和准确性,并提供了一个通用的框架&…...
招商蛇口 | 执笔CID,启幕低密生活新境
作为中国城市生长的力量,招商蛇口以“美好生活承载者”为使命,深耕全球111座城市,以央企担当匠造时代理想人居。从深圳湾的开拓基因到西安高新CID的战略落子,招商蛇口始终与城市发展同频共振,以建筑诠释对土地与生活的…...
Java求职者面试指南:计算机基础与源码原理深度解析
Java求职者面试指南:计算机基础与源码原理深度解析 第一轮提问:基础概念问题 1. 请解释什么是进程和线程的区别? 面试官:进程是程序的一次执行过程,是系统进行资源分配和调度的基本单位;而线程是进程中的…...
MySQL 索引底层结构揭秘:B-Tree 与 B+Tree 的区别与应用
文章目录 一、背景知识:什么是 B-Tree 和 BTree? B-Tree(平衡多路查找树) BTree(B-Tree 的变种) 二、结构对比:一张图看懂 三、为什么 MySQL InnoDB 选择 BTree? 1. 范围查询更快 2…...
【p2p、分布式,区块链笔记 MESH】Bluetooth蓝牙通信 BLE Mesh协议的拓扑结构 定向转发机制
目录 节点的功能承载层(GATT/Adv)局限性: 拓扑关系定向转发机制定向转发意义 CG 节点的功能 节点的功能由节点支持的特性和功能决定。所有节点都能够发送和接收网格消息。节点还可以选择支持一个或多个附加功能,如 Configuration …...
沙箱虚拟化技术虚拟机容器之间的关系详解
问题 沙箱、虚拟化、容器三者分开一一介绍的话我知道他们各自都是什么东西,但是如果把三者放在一起,它们之间到底什么关系?又有什么联系呢?我不是很明白!!! 就比如说: 沙箱&#…...
FFmpeg avformat_open_input函数分析
函数内部的总体流程如下: avformat_open_input 精简后的代码如下: int avformat_open_input(AVFormatContext **ps, const char *filename,ff_const59 AVInputFormat *fmt, AVDictionary **options) {AVFormatContext *s *ps;int i, ret 0;AVDictio…...
如何把工业通信协议转换成http websocket
1.现状 工业通信协议多数工作在边缘设备上,比如:PLC、IOT盒子等。上层业务系统需要根据不同的工业协议做对应开发,当设备上用的是modbus从站时,采集设备数据需要开发modbus主站;当设备上用的是西门子PN协议时…...









