一般写法:
char *my_strcpy(char *dst,const char *src)
{
assert(dst != NULL);
assert(src != NULL);
char *ret = dst;
while((* dst++ = * src++) != '\0') // 运算符优先级++高于*
;
return ret;
}
可以看到很简单,只需考虑三点。
1,判断源字符串和目的字符串是否为空
2,现将目的地址指针保存起来,方便输出
3,遍历原地址和目的地址,一个字符一个字符的复制,包括末尾的
但是上面的实现有问题,没有考虑到内存重合的情况。原地址src和目的地址dst所在内存有下面三种情况。
对于1和3的情况,不影响。虽然1也有重叠,但是重叠部分不会破坏源字符串内容。
对于,第二种情况,可以按照从后往前拷贝源字符串内容到目的字符串的思路进行处理。
void *do_copy(void *dst, const void *src, unsigned int count) {
assert(dst);
assert(src);
void *ret = dst;
if (dst <= src ||
(char *)dst >= ((char *)src + count)) //源地址和目的地址不重叠,低字节向高字节拷贝
{
while (count--) {
*(char *)dst = *(char *)src;
dst = (char *)dst + 1;
src = (char *)src + 1;
}
} else //源地址和目的地址重叠,高字节向低字节拷贝
{
dst = (char *)dst + count - 1;
src = (char *)src + count - 1;
while (count--) {
*(char *)dst = *(char *)src;
dst = (char *)dst - 1;
src = (char *)src - 1;
}
}
return ret;
}
char *do_strcpy(char *dst, const char *src) {
assert(dst != NULL);
assert(src != NULL);
char *ret = dst;
do_copy(dst, src, strlen(src) + 1);
return ret;
}