目录
一、内存拷贝函数——memcpy
1.函数声明:
注意:
2.函数使用用例:
3.memcpy函数的模拟实现:
二、内存拷贝函数2——memmove
1.函数声明:
2.memmove函数的模拟实现
三、内存比较函数——memcmp
1.函数声明:
2.函数使用实例:
四、内存设置函数——memset
1.函数声明:
2,函数使用实例:
一、内存拷贝函数——memcpy
1.函数声明:
void * memcpy ( void * destination, const void * source, size_t num );
解释:
①:作用:将source所指向的空间的内容的前num个字节的内容拷贝到destination指向的空间。
②:该函数有三个参数:
第一个参数是个void*的指针,指向目的地空间;
第二个参数是个void*的指针,用于指向源头空间;
第三个参数类型为size_t,代表待拷贝的字节数。
③:该函数的返回类型为void*,即目标空间destination的起始地址。
④:该函数包含在头文件<string.h>中。
注意:
1.想到“拷贝”两个字,很多贴子可能会想到“strcpy”,但一定要注意,“strcpy”函数只能用于字符串拷贝,而“memcpy”函数可能拷贝不同类型的数据(int*、char*、...等等),所以我们还可以看到,该函数的形参的两个指针都是void*型,就是为了接收不同类型的数据。
2.memcpy函数只能用于处理不重叠的内存的拷贝(如将数组下标为1,2,3,4,5的内容拷贝到该数组下标为3,4,5,6,7的位置,这种情况下标为3,4,5的内存空间就是重叠了),否则会产生错误。重叠内存的拷贝由另外一个函数——memmove来实现,介绍在下文。
2.函数使用用例:
#include<stdio.h>
#include<string.h>
int main()
{
//**********用例1***************************
int arr1[10] = { 1,2,3,4,5,6,7,8,9,0 };
int arr2[10] = { 0 };
memcpy(arr2, arr1, sizeof(arr1));
printf("arr2:");
for (int i = 0; i < 10; i++)
{
printf("%d ", arr2[i]);
}
printf("\n");
//**********用例2****************************
float arr3[5] = { 1.0,2.0,3.0,4.0,5.0 };
float arr4[5] = { 0 };
printf("arr4 ");
memcpy(arr4, arr3, sizeof(arr3));
for (int i = 0; i < 5; i++)
{
printf("%f ", arr4[i]);
}
return 0;
}
用例运行结果:
3.memcpy函数的模拟实现:
①:源代码
//函数模拟实现 #include<stdio.h> #include<string.h> #include<assert.h> void* my_memcpy(void* dest, void* sour, size_t size) { void* ret = dest; assert(dest && sour); while (size--) { *(char*)dest = *(char*)sour; dest = (char*)dest + 1; sour = (char*)sour + 1; } return ret; } int main() { int arr1[5] = { 1,2,3,4,5 }; int arr2[5] = { 0 }; my_memcpy(arr2, arr1, sizeof(arr1)); for (int i = 0; i < 5; i++) { printf("%d ", arr2[i]); } return 0; }
解释:
①:因为是模拟实现,所以返回类型和参数类型都要相同。
②:因为返回值为目标空间的起始地址,所以开始先创建一个void*的指针将目标空间的起始地址dest保存起来。
②:因为void*指针不能用于加减和解引用操作,所以必须强制转换为其他类型的指针,所以就要思考转化为什么类型?因为是以字节为单位,所以很显然转为化char*指针就可以一字节一字节的拷贝。所谓拷贝无非就是赋值操作。
③:我们知道是以字节为单位进行拷贝,所以循环次数即为待拷贝字节数size,所以用一个while循环即可,循环体里面就是拷贝部分,先将两个指针转化为char*的指针,这样解引用的访问权限就是一个字节,这样依次赋值下去,最后在返回目标空间的起始地址ret即可。
二、内存拷贝函数2——memmove
1.函数声明:
void * memmove ( void * destination, const void * source, size_t num );
解释:
①:我们发现该函数的返回类型及参数类型和“memcpy”函数都是一样的,不难理解,因为两者都是内存的拷贝,只是“memmove”函数有一点更高级的功能,就是可以对重叠的内存进行拷贝。
2.memmove函数的模拟实现
#include<stdio.h> #include<string.h> #include<assert.h> void* my_memmove(void* dest, void* sour, size_t sz) { assert(dest && sour); void* ret = dest; if (dest < sour) { //前->后 while (sz--) { *(char*)dest = *(char*)sour; dest = (char*)dest + 1; sour = (char*)sour + 1; } } else { //后->前 while (sz--) { *((char*)dest+sz) = *((char*)sour+sz); } } return ret; } int main() { int arr[10] = { 1,2,3,4,5,6,7,8,9,10 }; my_memmove(arr + 2, arr, 20); for (int i = 0; i < 10; i++) { printf("%d ", arr[i]); } int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 }; printf("\n"); my_memmove(arr1, arr1 + 2, 20); for (int i = 0; i < 10; i++) { printf("%d ", arr1[i]); } return 0; }
运行结果:
三、内存比较函数——memcmp
1.函数声明:
int memcmp ( const void * ptr1, const void * ptr2, size_t num );
解释:
①:该函数的作用就是将ptr1所指向的内容和ptr2所指向的内容进行比较,同样以字节为单位,但要注意的是,是以字节为单位进行比较,第三个参数num就是待比较字节数。
②:注意别和字符串比较函数“strcmp”混淆,“strcmp”只能用于字符串的比较,而此函数可以进行不同类型的数据的比较。
②:比较规则:(可参考函数“strcmp”)
若前大于后,返回一个大于0的数字;
若前等于后,返回0;
若前小于后,返回一个小于0的数字。
2.函数使用实例:
int main() { int arr1[] = { 1,2,3,4,5 }; int arr2[] = { 1,2,3,4,6 }; printf("%d\n", memcmp(arr1, arr2, 20)); return 0; }
很明显,arr1前四个数和arr2相同,但第五个数比arr2的第五个数小,所以会的到一个小于0的数,vs编译器默认这个小于0的数为-1,大于0的数为1.
四、内存设置函数——memset
1.函数声明:
void * memset ( void * ptr, int value, size_t num );
①:函数的作用就是将ptr所指向的空间的内容的前num个字节的内容设置成第二个参数的值value,一定要注意是以字节为单位,可参考使用实例。
②:返回值为ptr指向的空间的起始地址。
2,函数使用实例:
本次知识到此结束,希望对你有所帮助!