1 memcpy函数
memcpy是内存操作函数,所在的头文件是#include<string.h>。
1.1memcpy功能
memcpy和strcpy有一点相似,但是strcpy只能进行字符串的拷贝,而它可以对各种类型都能进行拷贝,但是按字节去进行拷贝的,就比如你有2个整形数组:a1和a2;你想将a2里面四个元素拷贝进a1中,一个整形是4个字节,那么就要拷贝16个字节。
下面是他的这个函数的传参内容:
主要是三个参数:你要拷贝进的地址destination,你要拷贝内容的地址source和你要拷贝的字节数num。
例如:
#include <stdio.h>
#include <string.h>
int main()
{
int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
int arr2[10] = { 0 };
memcpy(arr2, arr1, 20);
int i = 0;
for (i = 0; i < 10; i++)
{
printf("%d ", arr2[i]);
}
return 0;
}
1.2模拟实现memcpy
我们模拟实现这个函数首先从他的传参入手,你传入的是两个地址和一个整形
然后因为可以是任意类型,所以我们用两个void*去接收,然后就一个字节一个字节的去拷贝,但是void*这种类型的指针不能直接解引用。所以我们先要进行强制类型转换成char*然后在进行拷贝。因为char类型是占一个字节,我们也是一个字节一个字节的拷贝,所以强转成字符型比较符合我们的要求。
代码:
void my_memcpy(void* s1, const void* s2, size_t num) //void*的指针不能直接解应用
{
while (num--)
{
*(char*)s1 = *(char*)s2;
(char*)s1 = (char*)s1 + 1;
(char*)s2 = (char*)s2 + 1;
}
}
int main()
{
int num;//拷贝的字节数
int s1[20] = {1,2,3,4,5,6,7,9,0};
int s2[20] = { 2,3,4,5,6,7,89 };
scanf("%d", &num);
my_memcpy(s1, s2, num);
for (int i = 0; i <= 19; i++)
{
printf("%d", s1[i]);
}
return 0;
}
特别注意:memcpy对于destination和source有重叠的是候拷贝的结果是未定义,但是在我们vs2022memcpy是可以完成当这两个内存空间有重叠的情况。但是我们有另外一个操作数可以完成这个重叠时候的情况。
2 memmove函数
2.1memmove的功能
memmove函数可以去进行当destination和source有重合时就有可以用这个函数去进行拷贝。
也是按照字节去进行拷贝的,他的功能比memcpy多一些,
他的传参和memcpy一样。
用法举例:
#include <stdio.h>
#include <string.h>
int main()
{
int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
memmove(arr1+2, arr1, 20);
int i = 0;
for (i = 0; i < 10; i++)
{
printf("%d ", arr1[i]);
}
return 0;
}
2.2memmove的模拟实现
memmove因为可以进行重叠部分时拷贝的功能,所以他的模拟实现比memcpy稍微复杂一点。
这个重叠时候的情况还分为两种:
一种是destination在source的前面。
一种是source在destination的后面。
首先我们来讲第一种情况:
第一种情况是我们就要从前到后拷贝,这样你会将你没有进行拷贝的内容覆盖了,
第二种情况 就是需要我们要去从后往前拷贝才能不被覆盖掉。
void* my_memmove(void* destination, const void* source, int num)
{
if (destination < source)//前到后
{
while (num--)
{
*(char*)destination = *(char*)source;
destination = (char*)destination + 1;
source = (char*)source + 1;
}
}
else {//从后到前
while (num--)
{
*((char*)destination + num)=*((char*)source+num);
}
}
}
int main()
{
int s1[10] = { 1,2,3,4,5,6,7,8,9 };
int num;
scanf("%d", &num);
my_memmove(s1 + 3, s1 + 2,num);
for (int i = 0; i < 10; i++)
{
printf("%d", s1[i]);
}
return 0;
}
要注意的是当destination < source这一种情况是:
destination = (char*)destination + 1;
source = (char*)source + 1;
这两个语句不能写成destination++和source++;
因为我们这里的两个指针是void*
你要他自己去进行++的话,他不知道走多远,他没有具体类型,所以这里你要进行强转,再去进行++。
3 memset函数的使用
memset是⽤来设置内存的,将内存中的值以字节为单位设置成想要的内容ptr是你想改换内容的地址,value是想要你要改成什么内容,num是改多少个字节。
例如:
#include <stdio.h>
#include <string.h>
int main ()
{
char str[] = "hello world";
memset (str,'x',6);
printf(str);
return 0;
}
4memcmp函数的使用
这个函数是进行字节内容进行比较的
从ptr1和ptr2指针指向的位置开始,向后的num个字节进行比较 如果相同返回0; 不相同返回:ptr1>ptr2的话返回大于零的数,小于就是返回小于零的数。 例如:#include <stdio.h>
#include <string.h>
int main()
{
char s1[] = "DWgaOtP12df0";
char s2[] = "DWGAOTP12DF0";
int n;
n = memcmp(s1, s2, sizeof(s1));
if (n > 0)
printf("'%s' is greater than '%s'.\n", s1, s2);
else if (n < 0)
printf("'%s' is less than '%s'.\n", s1, s2);
else
printf("'%s' is the same as '%s'.\n", s1, s2);
return 0;
}
标签:函数,int,s1,char,source,num,内存,操作,拷贝 From: https://blog.csdn.net/2301_80028974/article/details/136721305