您的位置:首页 > 编程语言 > C语言/C++

模拟实现C语言字符串系列和memory系列库函数

2017-08-02 12:07 357 查看
string系列库函数

strcpy:对字符串的拷贝

char* my_strcpy(char* dst,const char* src)
{
assert(src);
assert(dst);
char *ret = dst;
while (*dst++ = *src++)
{}
//while (*src != 0)
//{
// *dst = *src;
// dst++;
// src++;
//}
//*dst = 0; //该目标字符串最后放入0结束
return ret;
}strncpy:对strcpy的变形,即拷贝字符串的前n个字符
char* my_strncpy(char* dst, const char* src,int n)
{
assert(src);
assert(dst);
char* ret = dst;
while (*dst && n>0)
{
*dst++ = *src++;
n--;
}
*dst = 0;
return ret;
}

strcmp:比较两字符串,相等返回0,str1>str2返回正数,str1<str2返回负数

int my_strcmp(char* str1, char* str2)
{
assert(str1);
assert(str2);
while (*str1 != 0 && *str2 != 0 && *str1 == *str2)
{
str1++;
str2++;
}
return *str1 - *str2;
}strncmp:在strcmp的基础上只比较n个字符
int my_strncmp(char* str1, char* str2, size_t n)
{
assert(str1);
assert(str2);
if (n == 0)
return 0;
//--n是将最后一次比较放在了return语句进行
while (--n && *str1 && *str2 && *str1 == *str2 )
{
str1++;
str2++;
}
return *str1 - *str2;
}
strcat:将str2追加至str1字符串
char* my_strcat(char* dst,const char* src)
{
assert(dst);
assert(src);
char* ret = dst;
while (*dst)    //将dst移至\0的位置
{
dst++;
}
while (*dst++ = *src++)  //\0已经从src拷贝至dst,不用额外加
{}
return ret;
}
strncat:将str2的前n个字符追加至str1
char* my_strncat(char* dst, const char* src,size_t n)
{
assert(dst);
assert(src);
if (n == 0)
return dst;
char* ret = dst;
while (*dst)
{
dst++;
}
while ((*dst++ = *src++) && --n)
{}
*dst = 0;
return ret;
}


memory系列函数

memcpy:对任意类型复制,包括但不限于字符串,需要指明复制的长度(以字节为单位),若dst和src内存地址有重叠,则会直接覆盖,不保证结果的正确性。
void* my_memcpy(void* dst,const void* src,size_t n)
{
assert(src);
assert(dst);
void* ret = dst;
while (n--)
{
*(char*)dst = *(char*)src;
dst = (char*)dst + 1;
src = (char*)src + 1;
}
return ret;
}memmove:与memcpy功能基本一致,若dst和src内存地址有重叠,memmove能够保证在覆盖之前将重叠区域复制到目标位置,但最终src会被修改。如没有内存重叠,则和memcpy作用一致。
如何解决内存重叠问题?

    1、若dst<=src  或者  dst>=src+n时,按顺序拷贝

    2、若dst>src  且  dst<src+n时,按逆序拷贝
void* my_memmove(void* dst, const void* src, size_t n)
{
assert(src);
assert(dst);
void* ret = dst;
if (dst <= src || (dst >= (char*)src + n)) //顺序复制
{
while (n--)
{
*(char*)dst = *(char*)src;
dst = (char*)dst + 1;
src = (char*)src + 1;
}
}
else //逆序复制
{
//将dst 和 src开始的位置从高地址开始向低地址变化
dst = (char*)dst + n - 1;
src = (char*)src + n - 1;
while (n--)
{
*(char*)dst = *(char*)src;
dst = (char*)dst - 1;
src = (char*)src - 1;
}
}

return ret;
}

问:strcpy、memcpy、memmove的区别?

strcpy:  

 只能复制字符串

memcpy:

可以复制任意类型,但内存重叠时不保证结果的正确性

memmove:

在内存覆盖时,保证结果是我们需要的结果,但会修改src的内容,若无内存重叠则和memcpy作用一致

9b61
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: