内存函数
一、memcpy使用和模拟实现
1.1参数
- 因为内存中不知道存的是什么类型的地址,所以函数的参数以及返回值都是void类型。
- 第一个参数是要拷贝到哪;第二个参数是从哪里拷贝;第三个参数是要拷贝的数据长度。
- 该函数不会检查是否有终止字符‘\0’,它会准确地复制num长度的数据。
- 为了避免溢出,destination和source的长度应至少为num。
- destination和source不能有重叠。
1.2 使用
1.3 模拟实现
void my_memcpy(void* arr2, void* arr1, size_t num)
{
while (num--)
{
*(char*)arr2 = *(char*)arr1;
((char*)arr2)++;
((char*)arr1)++;
}
}
int main()
{
int arr1[] = { 1,2,3,4,5,6 };
int arr2[2];
my_memcpy(arr2, arr1, 8);
int i = 0;
for (i = 0;i < 2;i++)
{
printf("%d ", arr2[i]);
}
return 0;
}
在模拟实现时,重点是对数据的拷贝,因为内存中存放的数据不知道其类型,因此我们把数据分成最小的单元也就是1个字节,对应char类型数据,因此将void类型强制转换成char类型的数据,然后通过while循环,遍历num个字节长度的数据,实现一定量数据的拷贝。
二、memmove使用和模拟实现
2.1 参数
- 注意:memmove和memcpy的区别就是,memmove所指向的两块空间可以有重叠。
2.2 使用
2.3 模拟实现
//展示其中一种特例
#include <assert.h>
void my_memmove(void* arr2, void* arr1, size_t num)
{
assert(arr1 && arr2);
if (arr1 <= arr2)
{
while (num--)
{
*((char*)arr2 + num) = *((char*)arr1 + num);
}
}
else
{
while (num--)
{
*((char*)arr2) = *((char*)arr1);
((char*)arr2)++;
((char*)arr1)++;
}
}
}
int main()
{
int arr1[] = { 1,2,3,4,5,6 };
my_memmove(arr1, arr1+1, 8);
int i = 0;
for (i = 0;i < 5;i++)
{
printf("%d ", arr1[i]);
}
return 0;
}
}
- 注意:在进行memmove的模拟实现时,应考虑重叠的情况,例如对一个字符串进行调整时,可能会出现:source地址分别>、<、=destination地址的情况,因此需要分情况来讨论。
三、memset使用
3.1 参数
- 参数一是一个指向所要修改的内存的地址;参数二是要修改成什么数值;参数三是修改几个字节个长度的数据。
3.2 使用
四、memcmp使用
4.1 参数
- 参数一和参数二是要比较的两个数据的地址;参数三是要比较的数据的长度。
- 内存1>内存2,打印一个大于0的数字;内存1<内存2,打印一个小于0的数字;内存1=内存2,打印0。
4.2 使用
比较的是12个字节,也就是前三个数字的大小,数组2的前三个数字比数组1前三个数字大,所以打印小于0的数字,-1。