如何部署thinkphp网站,如何上传自己的视频做网站,深圳建设局网站宝安分中心,自己网站怎么做外链目录 1.memcpy函数及其模拟实现 1.1 memcpy函数的使用 1.2 memcpy函数的模拟实现
2.memmove函数及其模拟实现 2.1 memmove函数的使用 2.2 memmove函数的模拟实现
3.memset函数
4.memcmp函数 1.memcpy函数及其模拟实现 1.1 memcpy函数的使用 memcpy函数是用来拷贝内存的函数其拷贝的方式为一个字节一个字节地拷贝使用时需要包含 string.h 的头文件。上面的 size_t num 参数的作用就是接收我们输入的想要拷贝的字节数destination的意思是目的地void* destination 参数是拷贝存放的目的地source是起源的意思const void* source就是我们所要拷贝的数据的起始地。两个接收地址的变量用 void* 类型来定义说明可以接收不同类型的地址。来看看具体使用: 这里我们将 arr 数组里20个字节的内存拷贝到 arr1 数组中去因为arr数组的类型为int型每个元素的大小为4个字节因此拷贝20个字节的内容相当于拷贝了 arr 中5个元素进 arr1 中。 需要注意的是如果 arr1 数组中本身有元素在拷贝的时候拷贝过去的元素会覆盖掉 arr1 中原有的元素: 操作字符串: 1.2 memcpy函数的模拟实现 下面我们来自己动手模拟实现一下memcpy函数:
//模拟实现memcpy函数
void* my_memcpy(void* dest, const void* src, size_t num)
{void* ret dest;//这一步是为了保存dest最开始指向的地址因为在后续循环里的操作里//dest的地址已经跑到后面去了不指向最开始的地址while (num--)//这里是总共循环的次数需要拷贝多少个字节就循环多少次{*(char*)dest *(char*)src;// 因为dest与src都是void*类型没法直接解引用操作又因为// memcpy函数是一个字节一个字节拷贝的因此我们在这进行拷贝操作的时候//将dest与src都强制类型转换为char*类型这样就可以达到一个字节一个字节拷贝的目的了dest (char*)dest 1;src (char*)src 1;//这里的操作是在拷贝完一个字节以后dest与src的地址都1//去找下一个字节地址进行下一个字节的拷贝}return ret;
}int main()
{int arr[] { 1,2,3,4,5,6,7,8,9,10 };int arr1[10] { 0 };my_memcpy(arr1, arr, 20);int i 0;for (i 0; i 10; i){printf(%d , arr1[i]);}return 0;
}
2.memmove函数及其模拟实现 2.1 memmove函数的使用 memmove函数的作用和memcpy函数几乎一样使用时也需要包含string.h的头文件但是memcpy函数相比于memmove函数来讲有一个缺陷下面来看一段代码:
这里我们想要将 arr 数组中 1,2,3,4,5 的数据拷贝到 arr 数组中 3,4,5,6,7 的位置那么结果按理来说应该最后输出打印的是 1,2,1,2,3,4,5,8,9,10。但实际上跟我们想的一样吗 没错想的和我们就是一样的可能这个时候就有人想说我在水字数了。哎此言差矣。虽然在这里最后输出的结果和我们设想的是一样的但是这仅是在VS编译器环境下一样而已换做别的编译器可能最后输出的就是下列结果: 为什么可能输出这个结果呢?我们来画图理解: 那么我们如果想要在一个数组里实现我们想要的效果该怎么办呢 这就需要用到memmove函数了memmove函数就可以专门用来处理这种拷贝内存与存放内存有重叠的情况: 在VS编译器中memcpy函数也能够完成memmove的作用我们不妨大胆猜测在VS中memcpy函数的实现是和memmove函数一样的。 2.2 memmove函数的模拟实现 下面我们来手动模拟实现一下memmove函数。 在模拟实现memmove函数之前我们需要搞清楚memmove函数的原理memmove函数的模拟实现相较于memcpy函数更为复杂我们来逐个讨论: ① 如何避免在拷贝内存的时候将后面需要拷贝的内存给改变呢?就像上面所说的改为 12121218910 的情况。这时候我们可以想到将内存从后往前拷贝不就行了就像这样: ② 用从前往后的方法就可以达到我们上面的目的但是这里又会出现一个新的问题如果我需要拷贝的内存在存放的内存后面呢就像下面这种情况: 这种情况从前往后存还适用吗我们画图来探究一下: 显然这个时候再采用从后往前的方法就不行了。既然从前往后不行那我们从前往后可行吗画图探究下: 可以发现这种情况从前往后拷贝存储是可行的那么除了这两种情况还有别的情况吗没有了需要拷贝的内存和拷贝内存目的地重复的情况一共就三种: ① 需要拷贝的内存在拷贝内存目的地前并且两者有重复部分 ② 需要拷贝的内存在拷贝内存目的地后并且两者有重复部分 ③ 两者完全重复 。而第三种情况不管怎么拷贝都能达到我们的目的因此在模拟实现memmove函数时我们只需要考虑前两种情况即可。下面来看代码: void* my_memmove(void* dest, const void* src, size_t num)
{if (dest src)//拷贝内存在拷贝存放的内存的前面并且有内存叠加{dest (char*)dest num - 1;//将dest和src分别指向各自的最后一个字节src (char*)src num - 1;while (num--)//将内容一个字节一个字节进行拷贝{*(char*)dest *(char*)src;dest (char*)dest - 1;src (char*)src - 1;}}else{while (num--)//拷贝内存在拷贝存放的内存的后面并且有内存叠加{*(char*)dest *(char*)src;//直接从第一个字节拷贝dest (char*)dest 1;src (char*)src 1;}}
}int main()
{int arr[] { 1,2,3,4,5,6,7,8,9,10 };my_memmove(arr2, arr, 20);int i 0;for (i 0; i 10; i){printf(%d , arr[i]);}return 0;
}
3.memset函数 memset函数顾名思义就是用来设置内存将需要设置的内存中的值按照字节来设置成想要的内容使用时也需要包含string.h的头文件。 这里我们用memset函数将字符串s的前三个字节的内容改为了字符 x 。
4.memcmp函数 memcmp函数是用来比较内存的用法与strcmp函数十分相似不同的是strcmp函数是专门用来比较字符串的函数而memcmp函数则可以用来比较各种类型。 这里的意思就是当所比较的两个字符串前一个大于后一个则返回一个大于0的数反之则返回小于0的数相等则返回0。 这里我们调用的memcmp的时候将 s 与 s1 进行比较如果 s s1 则返回一个大于0的数反之则返回小于0的数如果相等则返回0。这里 s 的第一个字符是a而 s1 的第一个字符是b在第一个字符就判断出了大小后面也不用判断了直接返回了小于0的数。 创作不易点个赞再走呗求求啦~