memcpy:实现两个指针内容的拷贝
如何使用?
可以看出memcpy函数需要接收的参数为void*,const void*,size_t。destination是指目标指针,source是指源头指针,而第三个参数size_t num是要拷贝过去的字节数(特别注意不是元素个数),结合起来看就是从内存的角度实现把source里 num个字节的内容 拷贝到destination中。
结合下面的例子品一下:
拷贝字符串
int main()
{
char arr1[100] = "abcdefjhppq";
char arr2[100] = "ENGLISH";
memcpy(arr1, arr2, 7 * sizeof(char));
//destination source num
printf("%s\n", arr1);//返回arr1的首地址来打印字符串
return 0;
}
拷贝整型
int main()
{
int arr1[10] = {1,2,3,4,5,6,7,8,9,10};
int arr2[5] = {100,200,300,400,500};
memcpy(arr1, arr2, 5 * sizeof(int));
//destination source num
for (int i = 0; i < 10; i++)
{
printf("%d ", arr1[i]);
}
return 0;
}
模拟实现memcpy:
void* my_memcpy(void* dest, const void* sour, size_t num)
{
char* ret = dest;//定义一个指针存放目标指针的首地址用于最后的返回值
//num一进去是4个字节,然后减1。直到num=1先进去完成循环再自减为0,跳出去,执行循环4次。
while (num)
{
*(char*)dest = *(char*)sour;//他俩都是void*型 不能直接解引用 所以强制类型转换
(char*)dest=(char*)dest+1;
//为何强转为char*?因为操作的num是以1个字节为单位,char*型指针每次刚好跳过1个字节
//若强转成(int*)每次跳4个字节,如果我想操作奇数个字节就麻烦了
(char*)sour=(char*)sour+1;
num--;
}
return ret;
}
int main()
{
char arr1[] = "abcdefjh";
char arr2[] = "HAHEHO";
my_memcpy(arr1, arr2, 4 * sizeof(char));
printf("%s\n", arr1);//盼望得到:HAHEefjh
return 0;
}
完成!!
memmove:实现 有重叠内存空间的 指针的拷贝
对比刚刚的memcpy,前者实现的是 指向两块不同内存空间的指针 的内容的拷贝,并不期望它来完成有重叠空间的任务,例如实现一个字符串之间的拷贝:abcdefj 把efj拷贝到abc上变成 efjdefj。
而memmove就是用来实现上述功能的函数。
先来看如何使用它:
参数和返回值同memcpy一样。
看个例子来使用它:
int main()
{
char arr[] = "abcdefjABCDEFJ";
memmove(arr, arr + 7, 5*sizeof(char));
printf("%s\n", arr);
return;
}
模拟实现:
void* my_memmove(void* dest, const void* sour, size_t num)
{
void* ret = dest;
while (num--)
{
*(char*)dest = *(char*)sour;
(char*)dest = (char*)dest + 1;
(char*)sour = (char*)sour + 1;
}
return ret;
}
int main()
{
int arr[10] = { 1,200,300,400,500,6,7,8,9,100 };
my_memmove(arr, arr + 2, 3 * sizeof(int));
//打印数组
for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)
{
printf("%d ", arr[i]);
}
return 0;
}
那如果目标在源头之后呢?还能从两个数组的头部开始拷贝吗?
看下代码:
void* my_memmove(void* dest, const void* sour, size_t num)
{
void* ret = dest;
while (num--)
{
*((char*)dest + num) = *((char*)sour + num);
//从两个指针的末端开始拷贝,所以加num,从最后一个字节开始,随着num的减少向前移
}
return ret;
}
int main()
{
int arr[10] = { 1,2,300,400,500,6,7,8,9,100 };
my_memmove(arr + 2, arr, 3 * sizeof(int));
for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)
{
printf("%d ", arr[i]);
}
return 0;
}
以上两种情况用if和else结合一下就很好了:
void* my_memmove(void* p1, const void* p2, size_t num)
{
void* ret = p1;
if (p1 < p2)
{
while (num--)
{
*(char*)p1 = *(char*)p2;
p1 = (char*)p1 + 1;
p2 = (char*)p2 + 1;
}
}
else
{
while (num--)
{
*((char*)p1 + num) = *((char*)p2 + num);
}
}
return ret;
}
int main()
{
int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
my_memmove(arr+3, arr, 5 * sizeof(int));
for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)
{
printf("%d ", arr[i]);
}
return 0;
}
memset:设置内存中的内容
memset是用来设置内存的,将内存中的值以字节为单位设置成想要的内容。
ptr指向要修改的内容,value是你要填充的内容,num是value的字节数。
看下例子来使用它:
int main()
{
char str[] = "hello world";
memset(str, '*', 6);
printf(str);
return 0;
}
memcmp:比较从两个指针开始向后num个字节的内容
返回值如下:prt1<ptr2--<0
= --0
> -->0
下例子使用它:
int main()
{
char buffer1[] = "DWgaOtP12df0";
char buffer2[] = "DWGAOTP12DF0";
int n;
n = memcmp(buffer1, buffer2, sizeof(buffer1));
if (n > 0)
printf("'%s' is greater than '%s'.\n", buffer1, buffer2);
else if (n < 0)
printf("'%s' is less than '%s'.\n", buffer1, buffer2);
else
printf("'%s' is the same as '%s'.\n", buffer1, buffer2);
return 0;
}
以上就是我对C语言中的内存函数的理解,感谢观看~