1.memcpy(两者引用的头文件均是<stdlib.h>)
这个函数适用于开辟了两个空间的字符串数组,无法进行自身与自身的拷贝。eg:
char* my_memcpy(void* s1, void* s2,int count) {
char* start = s1;
while (count--) {
*(char*)s1 = *(char*)s2;
(char*)s1 += 1;
(char*)s2 += 1;
}
return start;
}
int main() {
char str[20] = "bcde";
char* str1 = "abcd";
char* s = my_memcpy(str, str1, 3);
printf("%s", s);
return 0;
}
2.memmove
这个函数则考虑了自身与自身的拷贝,实际上,内置的memcpy实际上是直接使用了memmove的代码,而没有用有缺陷的memcpy的代码,这个函数则做到了可以处理自身拷贝。接下来对具体的过程进行解析:
这个图展现的就是为什么memcpy无法做到memmove效果的原因,因为在拷贝的过程中已经被覆盖了。那要如何做到不覆盖呢?考虑两种情况:
(1)要接受拷贝的位置(既3的地址)在模板首地址(既1的地址)后面,可以考虑使用下面这个处理方式:
既:先由4到6(蓝色的线)一直到1到3(紫色的线)由后往前拷贝,这样就得避免覆盖;
(2)反之,则可考虑由前往后,如图:
既由4到1,5到2,6到3,7到4这样的顺序,这样也能够很好地避免覆盖问题。
于是就有了以下实现的代码:
char* my_memmove(void* s1, void* s2,int count) {
char* start = (char*)s1;
if ((char*)s1 < (char*)s2) {
while (count--) {
*(char*)s1 = *(char*)s2;
(char*)s1 += 1;
(char*)s2 += 1;
}
}
else {
while (--count>=0) {
*((char*)s1 + count) = *((char*)s2 + count);
}
}
return start;
}
int main() {
char str[20] = "bcde";
char* str1 = "abcd";
char* s = my_memmove(str, str+1, 3);
printf("%s", s);
return 0;
}
打印结果如下: