目录
一.memcpy函数
(1)mempcy函数介绍
内存拷贝函数
说明一:第一个参数是目的地指针,第二个参数是源头指针,第三个参数是拷贝字节的大小,返回值是void*
说明二:memcpy从源头的位置开始向后复制num个字节的数据到目的地的内存位置.
说明三:这个函数遇到'\0'的时候并不会停下来
说明四:如果源头和目的地有任何重叠,复制的结果都是未定义的
举例:
拷贝整形数组
int arr1[] = { 1,2,3,4,5 };
int arr2[10] = { 0 };
memcpy(arr2, arr1, sizeof(arr1));
内存布局: memcpy执行后
整形数组就这样被拷贝了!!
我们在试下拷贝结构体数组
先声明结构体
struct S {
char name[20];
int age;
};
创建两个结构体数组,准备吧arr3拷贝到arr4
struct S arr3[] = { {"张三",20},{"李四",30} };
struct S arr4[3] = { 0 };memcpy(arr4, arr3, sizeof(arr3));
内存布局:
拷贝前 拷贝后
可见,结构体数组也能被拷贝过去!!
(2)模拟实现memcpy
声明函数
void* my_memcpy(void* dest, const void* src, size_t num) {
void* ret = dest;
assert(dest != NULL);
assert(src != NULL);
while (num--)
{
*(char*)dest = *(char*)src;
++(char*)dest;
++(char*)src;
}
return ret;
}
代码实现:
int main() {
int arr1[] = { 1,2,3,4,5 };
int arr2[10] = { 0 };
my_memcpy(arr2, arr1, sizeof(arr3));
return 0;
}
(3)注意事项
用上面自己写的函数测试下面的代码,代码的目的是arr自己的前5个元素拷贝到下标起始是2的位置处.
int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
int i = 0;
my_memcpy(arr + 2, arr, 20);
for (i = 0; i < 10; i++)
{
printf("%d ", arr[i]);
}
输出打印结果.
结果让人意外,输出的内容与所想的不一样.这是因为数组自己给自己拷贝的时候,已经拷贝的位置数 据发生了变化,这是一种源空间和目标空间出现了重叠的情况
也就是所写的函数存在问题,这就要介绍下一个内存函数了,这个内存函数能解决这个问题
二.memmove函数
(1)memmove函数介绍
说明一:和memcpy差别就是memmove函数处理的原内存块和目标内存块是可以重叠的.
说明二:如果源空间和目标空间出现重叠,就得使用memmove
说明三:第一个参数是目的地指针,第二个参数是源头指针,第三个参数是拷贝字节的大小,返回值是void*
举例:
使用memmove,拷贝前五个元素到第3个位置.
int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
int i = 0;
memmove(arr + 2, arr, 20);
for (i = 0; i < 10; i++)
{
printf("%d ", arr[i]);
}
打印结果
(2)模拟实现memmove
声明函数
void* my_memmove(void* dest, const void* src, size_t count) {
void* ret = dest;
assert(dest != NULL);
assert(src != NULL);
if (dest<src)
{
while (count--)
{
*(char*)dest = *(char*)src;
++(char*)dest;
++(char*)src;
}
}
else
{
while (count--)
{
*((char*)dest + count) = *((char*)src + count);
}
}
return ret;
}
代码实现:
int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
my_memmove(arr + 2, arr, 20);
int i = 0;
for (i = 0; i < 10; i++)
{
printf("%d ", arr[i]);
}
三.memcmp函数
(1)memcmp函数介绍
说明一:比较从ptr1和ptr2指针开始的num个字节,也就是第一个参数是ptr1指针,第二个参数是ptr2指针,第三个是比较的字节大小
说明二: 返回值分别是1 0 -1,跟strcmp一样
举例:
int arr1[] = { 1,2,3,4,5 };
int arr2[] = { 1,2,5,4,3 };
int ret=memcmp(arr1, arr2, 9);
printf("%d\n", ret);
输出
返回的是-1,arr2大于arr1
两个数组的排列大致是这样的
由于两个数组第9的个字节相比较,得03<05,所以返回了-1
四.memset-内存设置
(1)memset内存介绍
说明一:内存设置,一块空间设置指定字符
说明二:第一个参数是目的地的指针参数,第二个参数是设置的字符,第三个参数是设置的长度
举例:
int arr[10] = "";
memset(arr, '#', 10);
内存布局:
使用前 使用后
举第二个例子:
int arr[10] = { 0 };
memset(arr, 1, 10);
内存布局:
使用前 使用后
可以看出,memset操作的是字节,