memcpy使用和模拟实现
memcpy使用
void * memcpy ( void * dest, const void * src, size_t num );
1.函数memcpy从src(源空间)的位置开始向后复制num个字节的数据到dest(目标空间)指向的内存位置
2.这个函数在遇到\0的时候并不会停下来
3.如果src和dest有任何的重叠,复制的结果都是未定义的(不重叠内存的拷贝)
4.头文件string.h
5.函数返回目标空间的起始地址
#include <stdio.h>
#include <string.h>int main()
{int arr1[] = { 1, 2, 3, 4, 5 };int arr2[10] = { 0 };memcpy(arr2, arr1, sizeof(arr1));int i = 0;for (i = 0; i < 10; i++){printf("%d ", arr2[i]);}printf("\n");return 0;
}
memcpy模拟实现
#include <stdio.h>
#include <assert.h>//不重叠内存的拷贝
void* my_memcpy(void* dest, const void* src, size_t num)
{assert(dest && src);//断言,预防野指针void* ret = dest;//记录目标空间的起始地址,以便返回while (num--)//num次循环{//每次循环处理1个字节的数据*((char*)dest) = *((char*)src);dest = (char*)dest + 1;src = (char*)src + 1;}return ret;//返回目标空间的起始地址
}int main()
{int arr1[] = { 1, 2, 3, 4, 5 };int arr2[10] = { 0 };my_memcpy(arr2, arr1, sizeof(arr1));int i = 0;for (i = 0; i < 10; i++){printf("%d ", arr2[i]);}printf("\n");return 0;
}
memmove使用和模拟实现
对于重叠的内存,交给memmove来处理
memmove使用
void * memmove ( void * destination, const void * source, size_t num );
1.和memcpy的差别就是memmove函数处理的源内存块和⽬标内存块是可以重叠的。
2.如果源空间和⽬标空间出现重叠,就得使⽤memmove函数处理。
#include <stdio.h>
#include <string.h>int main()
{int arr1[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };// 1 2 1 2 3 4 5 8 9 10memmove(arr1 + 2, arr1, 20);//将1 2 3 4 5拷贝到3 4 5 6 7位置处int i = 0;for (i = 0; i < 10; i++){printf("%d ", arr1[i]);}printf("\n");return 0;
}
memmove模拟实现
memmove可以处理不重叠+重叠内存的拷贝
而重叠内存的拷贝分两种情况
第一种: dest < src
int arr1[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };// 3 4 5 6 7 6 7 8 9 10 //dest srcmy_memmove(arr1, arr1 + 2, 20);//将3 4 5 6 7拷贝到1 2 3 4 5位置处
该种情况与memcpy模拟实现的拷贝方式相同
第二种:dest >= src
int arr1[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };// 1 2 1 2 3 4 5 8 9 10// dest srcmy_memmove(arr1 + 2, arr1, 20);
下面是代码实现
#include <stdio.h>
#include <assert.h>void* my_memmove(void* dest, const void* src, size_t num)
{assert(dest && src);//断言void* ret = dest;//记录目标空间的起始地址if (dest < src)//情况1,与memcpy模拟实现的代码相同{//前->后while (num--){*((char*)dest) = *((char*)src);dest = (char*)dest + 1;src = (char*)src + 1;}}else//情况2:dest>=src{//后->前while (num--)//第一次num--后num变为19{//dest强转为char*并向后移动19个字节,访问最后一个字节,再解引用找到其内容//src等同dest,最后将dest中的内容赋值给src*((char*)dest + num) = *((char*)src + num);//下一次循环进来num变为18,继续赋值,直到num为0}}return ret;//返回目标空间的起始地址}int main()
{//int arr1[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };// 1 2 1 2 3 4 5 8 9 10//my_memmove(arr1 + 2, arr1, 20);//后->前int arr1[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };// 3 4 5 6 7 6 7 8 9 10 my_memmove(arr1, arr1 + 2, 20);//前->后int i = 0;for (i = 0; i < 10; i++){printf("%d ", arr1[i]);}printf("\n");return 0;
}
memset函数的使用
void * memset ( void * ptr, int value, size_t num );
memset是⽤来设置内存的,将内存中的值以字节为单位设置成想要的内容。
#include <stdio.h>
#include <string.h>int main()
{char arr[] = "hello world";// hexxxxxxxldmemset(arr + 2, 'x', 7);//从arr+2地址处开始向后7个字节设置成'x'printf("%s\n", arr);return 0;
}
#include <string.h>int main()
{int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };memset(arr, 1, 40);//想把arr中的元素全改成1,这样是不行的//因为它是按字节设置的,内存中:01010101memset(arr, 0, 40);//所以我们一般都把它用来设置0return 0;
}
memcmp函数的使用
int memcmp ( const void * ptr1, const void * ptr2, size_t num );
⽐较从ptr1和ptr2指针指向的位置开始,向后的num个字节
返回值:
ptr1指向的位置向后的num个字节中的内容大于ptr2中的内容,返回>0的值
相等,返回0。小于,返回<0的值。
#include <string.h>int main()
{int arr1[] = { 1, 2, 3, 4, 5 };int arr2[] = { 1, 2, 3, 4, 0x12233301 };int r = memcmp(arr1, arr2, 16);//arr1和arr2中前16个字节的内容相等printf("%d\n", r);//0return 0;
}
int main()
{int arr1[] = { 1, 2, 3, 4, 5 };//内存中arr1:0100000002000000030000000400000005000000//内存中arr2:0100000002000000030000000400000001332312int arr2[] = { 1, 2, 3, 4, 0x12233301 };//arr1的第17个字节的内容为05大于arr2中的01int r = memcmp(arr1, arr2, 17);printf("%d\n", r);//>0return 0;
}