前言
个人主页: :金句分享:
✨未来如星辰大海般璀璨✨
✨不必踌躇于过去的半亩方塘.✨
目录
- 前言
- 一、memcpy函数
- 函数模型:
- 函数参数:
- 函数的应用:
- 函数的模拟实现:
- 二、memmove函数
- 函数模型:
- 函数参数:
- 函数模拟实现
- 三、memcmp函数
- 函数模型:
- 函数参数:
- 函数应用:
- 模拟实现
- 四、memset函数
- 函数模型:
- 函数参数
一、memcpy函数
函数模型:
函数参数:
参数 | 意义 |
---|---|
destination | 指向目的地地址的指针,类型转换为 void* 类型的指针。 |
source | 指向要复制的数据源的指针,类型转换为 const void* 类型的指针。 |
num | 要复制的字节数 |
函数头文件:
#include
函数功能:
函数memcpy从source的位置开始向后复制num个字节的数据到destination的内存位置。
注意:
要保证目的地址存的下源地址的内容,要守规矩哦!
1.为什么有了strcpy函数还要有memcpy函数呢” />
函数参数:
参数 | 意义 |
---|---|
destination | 指向目的地地址的指针,类型转换为 void* 类型的指针。 |
source | 指向要复制的数据源的指针,类型转换为 const void* 类型的指针。 |
num | 要复制的字节数 |
函数作用:
该函数与memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠
的。
如果源空间和目标空间出现重叠,就得使用memmove函数处理,其实在有的编译器中,对于memcpy函数也进行了优化,也是允许内存重叠的.
但牛牛认为,还是有必要掌握这种更”稳妥”的函数的.
情况1
这种情况我们可以正常的从前向后(前->后) 拷贝.
即:先将6拷贝至2位置,再讲7拷贝至3位置……
这种情况我们使用从从前向后(前->后)拷贝则达不到我们的要求.
如果我们先将6拷贝至8处,7拷贝至9处,则原来的8 9都被修改了.
这时我们需要从后往前(后->前)拷贝.
即先将11拷贝至13处,再将9拷贝至12处……
其实这种情况并不是内存地址重叠,目的地址出现在前面也是一样的,都是可以从前向后(前->后)拷贝和从后往前(后->前)拷贝皆可.
函数模拟实现
#include #includevoid* my_memmove(void* destination, const void* source, size_t num){void* ret = destination;//保留目的地原来的首地址assert(destination && source);//防止传错地址if (destination < source)//情况1时,目的地址的首地址小于源地址首地址{//前-->后while (num--){*(char*)destination = *(char*)source;((char*)destination)++;((char*)source)++;}}else{//后->前while (num--){*((char*)destination + num) = *((char*)source + num);//注意,这里如果以destination为1的偏移量,+num则是目的地地址的最后一个元素的地址.}}return ret;}
代码测试:
情况1;
int main(){int arr[] = { 1,2,3,4,5,6,7,8,9,11,12,13 };//情况1my_memmove(arr + 1, arr + 5, sizeof(int) * 5);int sz= sizeof(arr) / sizeof(arr[0]);for (int i = 0; i < sz; i++){printf("%d ", arr[i]);}return 0;}
运行结果:
1 6 7 8 9 11 7 8 9 11 12 13
情况2:
int main(){int arr[] = { 1,2,3,4,5,6,7,8,9,11,12,13 };//情况1my_memmove(arr +7, arr + 5, sizeof(int) * 5);int sz = sizeof(arr) / sizeof(arr[0]);for (int i = 0; i < sz; i++){printf("%d ", arr[i]);}return 0;}
运行结果:
1 2 3 4 5 6 7 6 7 8 9 11
三、memcmp函数
函数模型:
函数参数:
参数 | 意义 |
---|---|
ptr1 | 指向要比较的内容1,指针 |
ptr2 | 指向要比较的内容2,指针 |
num | 要比较的字节个数 |
函数头文件:
#include
函数功能
比较从ptr1和ptr2指针开始的num个字节.
注意与strcmp函数区分:
strcmp函数:用于比较字符串是否相等,只用于比较字符
memcmp:按字节比较,两个指针所指向的内容是否相等.可用于比较不同类型的元素,但是是按字节比较.
返回值 | 意义 |
---|---|
<0 | 第一个不想等的字节中的值的str1的值小于str2中的值(arr1 |
0 | 两个指针的内容相等 |
>0 | 第一个不相等的字节的str1的值大于于str2中的值(arr1>arr2 |
函数应用:
试着猜一下这段代码的值” />
答案:
0
解析:
首先这里是小端存储模式.则这两个数组在内存中存储的是:
arr1 :01 00 00 00 04 00 00 00 07 00 00 00 FF 00 00 00 (16进制,两位代表一个字节)
arr2 :01 00 00 00 04 00 00 00 07 00 00 00 FF 10 00 00
很明显,这里前四个元素(1,4,7)是相等的,而元素255和元素511则是第一个字节的内容相等,所以当比较的元素是[0,13]时,memcmp函数会认为这两个指针所指向的内容是相同的,故返回值是0.
可以试着改成14字节,返回值会是-1,因为第14个字节,arr1是00.arr2是1,则arr1
模拟实现
#includeint my_memcmp(const void* ptr1, const void* ptr2, size_t num){assert(ptr1 && ptr2);while (num--)//比较num个字节{if (*(char*)ptr1 == *(char*)ptr2)//相等继续往后比较{((char*)ptr1)++;((char*)ptr2)++;}else if (*(char*)ptr1 > *(char*)ptr2)//str1大则返回大于0的数{return 1;}else//str2大返回小于0的数{return -1;}}return 0;//比完了num个字节都相等则返回0}
四、memset函数
函数模型:
头文件:
#include
函数参数
参数 | 意义 |
---|---|
ptr | 指向要设置内容的空间 |
value | 要设置的值,虽然是整形类型,但是也可以是字符,字符会转化为对应的ASCII码值 |
num | 要设置空间内容的字节个数 |
函数功能:
将ptr所指向的空间,的num个字节设置为value值,注意这里也是按字节设置.
示例:
#include #include int main(){int arr[5] = { 0 };memset(arr, 1, 20);for (int i = 0; i < 5; i++){printf("%d ", arr[i]);}return 0;}
结果会是下面这个吗” />
执行语句memset(arr, 1, 40);后
很显然,这里是将20个字节设置为了1,而一个整形占4个字节;
那么怎样才可以将每个元素都设置为1呢” />