上一篇文章详细介绍了字符串函数,那字符串函数和内存函数到底有什么区别呢?
最根本的区别在于,他们操作的对象不同,视角不同。
字符串函数针对的是一个个的字符,而内存函数顾名思义关注的是内存,存储在内存中的一个个字节。
复制内存块,可以将任意类型的数据进行拷贝。
将source的num个字节的内容拷贝到destination内存中
前面两个参数分别是目标内存的起始地址和源内存的起始地址,第三个参数是需要拷贝内容的字节个数。
返回值是destination的首元素地址
#include
char* my_memcpy(void* dest, const void* sou, size_t num)
{
void* ret = dest;
while (num--)
{
*(char*)dest = *(char*)sou;
//(char*)dest++;
dest = (char*)dest + 1;
sou = (char*)sou + 1;
}
return ret;
}
int main()
{
int arr1[20] = { 0 };
int arr2[] = { 1,2,3,4,5,6,7 };
my_memcpy(arr1, arr2, 21);
for (int i=0;i<10;i++)
{
printf("%d ", arr1[i]);
}
return 0;
}
与memcpy函数功能相似,但是memmove函数功能更强大,可以拷贝带有重叠的内存块,因此我们以后可以直接采用memmove函数去拷贝内容,不论是重叠或不重叠 。
比如我们有这样的一段内存,然后soul为起始地址,传3个整型(12个字节)到dest位置上。
但是如果用memcpy拷贝的方法,发现已经先把1覆盖到了3的位置,所以3就变成了1,之后再想拷贝3发现已经被覆盖为1,所以此法不通。
我们可以从后向前拷贝,先将sou最后的3拷贝到dest最后的5,接着再向前拷贝,这样就避免了重叠的问题
还是一样的需求,把sou为起始地址,传3个整型(12个字节)到dest位置上。
但这时再从后向前拷贝,会将3重叠为5,之后再想拷贝3,就会变成5.
我们从前向后拷贝,从sou的3开始拷贝,这样也避免了重叠问题。
遇到不同的情况,我们采取不同的措施,分情况的标准就是sou,和dest的地址高低,若sou
#include
void* my_memmove(void* dest, void* soul, size_t num)
{
void* ret = dest;
if (soul < dest)
{
dest = (char*)dest + num-1;//需要减去1,因为+1就是两个字节了
soul = (char*)soul + num-1;
while (num--)
{
*(char*)dest = *(char*)soul;
dest = (char*)dest - 1;
soul = (char*)soul - 1;
}
}
else
{
while (num--)
{
*(char*)dest = *(char*)soul;
dest = (char*)dest + 1;
soul = (char*)soul + 1;
}
}
return ret;
}
int main()
{
int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };
my_memmove(arr1, arr1+2, 12);
for (int i=0;i<10;i++)
{
printf("%d ", arr1[i]);
}
return 0;
}
两个指针指向的内容进行比较,并从起始位置往后的num个字节内容进行比较
参数为两个指针,并且加上限制字节的个数
返回值,如果前者大于后者,返回大于0的数字,如果前者小于后者,返回小于0的数字,两者相等,返回0。
以字节为单位,将ptr指向的内容修改为num个字节的value值
上面是char类型,下面是int类型,int类型更便于我们理解
时时刻刻要想到内存函数操作的对象是字节,比如上面的整型例子,memset操作了10个字节,相当于把两个整型的内容改成01 01 01 01,然后第三个元素改成01 01 00 00