模拟库函数的中strcpy、strncpy、memcpy、memove、strcat、 strncat、 strcmp 、strncmp 、strstr、 strchr、 strlen、
直接贴代码,代码有注释
strcpy、strncpy
//des必须有足够的空间去容纳source,char[],
//des与source不能存在内存重叠、
//为什么返回char* ,为了实现链式表达式
char * my_strcpy(char * dst, const char * source)
{
assert(dst != NULL && source != NULL);
char* res = dst;
while ((*dst++ = *source++) != '\0')
;
return res;
}
//函数并没有为dst添加\0;src个数小于num个,那么提前结束
//count的值必须小于dst的长度
char * my_strncpy(char * dst, const char * src, size_t count)
{
assert(dst != NULL && src != NULL);
char *tmp = dst;
//先把\0复制过去,count没有--
while (count && (*tmp++ = *src++) != '\0')
--count;
//所以count要先减1
if (count)
{
while (--count)
*tmp++ = '\0';
}
return dst;
}
memcpy memove
//内存拷贝,没有考虑内存重叠的问题
void * my_memcpy(void * dst,const void * src, size_t count)
{
assert(dst != NULL && src != NULL);
void * ret = dst;
while (count--) {
*(char *)dst = *(char *)src;
dst = (char *)dst + 1;
src = (char *)src + 1;
}
return(ret);
}
//
void * my_memmove(void * dst, const void * src, size_t count)
{
assert(dst != NULL && src != NULL);
void *res = dst;
if (dst <= src || (char *)dst >= ((char *)src + count))
{
// Non-Overlapping Buffers
while (count--)
{
*(char *)dst = *(char *)src;
dst = (char *)dst + 1;
src = (char *)src + 1;
}
}
else
{
//Overlapping Buffers
//从后往前拷贝
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(res);
}
strcat strncat
char * my_strcat(char * dst,const char * src)
{
assert(dst != NULL && src != NULL);
char * cp = dst;
while (*cp != '\0')
cp++;
while (*cp++ = *src++);
return(dst);
}
char * my_strncat(char * front,const char * back, size_t count)
{
assert(front != NULL && back != NULL);
char *start = front;
//找到front的结尾
//while (*front != '\0')
// front++;
while (*front++)
;
front--;//front 在'\0'后面
while (count--)
if (!(*front++ = *back++))//等于'\0'执行return
return(start);
*front = '\0';
return(start);
}
* strcmp strncmp *
int my_strcmp(const char * src,const char * dst)
{
int ret = 0;
while (!(ret = *(unsigned char *)src - *(unsigned char *)dst) && *dst)
++src, ++dst;
//注意上面src后面是逗号
if (ret < 0)
ret = -1;
else if (ret > 0)
ret = 1;
return(ret);
}
//这是库函数中实现的strncmp函数,它以四个字节划分,可能是为了效率问题吧。
int my_strncmp1(const char *first,const char *last,size_t count)
{
assert(first != NULL && last != NULL);
size_t x = 0;
if (!count)
{
return 0;
}
/*
* This explicit guard needed to deal correctly with boundary
* cases: strings shorter than 4 bytes and strings longer than
* UINT_MAX-4 bytes .
*/
if (count >= 4)
{
/* unroll by four */
for (; x < count - 4; x += 4)
{
first += 4;
last += 4;
if (*(first - 4) == 0 || *(first - 4) != *(last - 4))
{
return(*(unsigned char *)(first - 4) - *(unsigned char *)(last - 4));
}
if (*(first - 3) == 0 || *(first - 3) != *(last - 3))
{
return(*(unsigned char *)(first - 3) - *(unsigned char *)(last - 3));
}
if (*(first - 2) == 0 || *(first - 2) != *(last - 2))
{
return(*(unsigned char *)(first - 2) - *(unsigned char *)(last - 2));
}
if (*(first - 1) == 0 || *(first - 1) != *(last - 1))
{
return(*(unsigned char *)(first - 1) - *(unsigned char *)(last - 1));
}
}
}
/* residual loop */
for (; x < count; x++)
{
if (*first == 0 || *first != *last)
{
return(*(unsigned char *)first - *(unsigned char *)last);
}
first += 1;
last += 1;
}
return 0;
}
int my_strncmp2(const char *first, const char *last, size_t count)
{
assert(first);
assert(last);
if (count == 0)
return 0;
while (count)
{
if (*first == '0' || *first != *last)
return *first - *last;
first++;
last++;
count--;
}
return 0;
}
* strstr strchr*
char * my_strstr(const char * str1,const char * str2)
{
assert(str1); assert(str2);
char *cp = (char *)str1;
char *s1, *s2;
if (!*str2)
return((char *)str1);
while (*cp)
{
s1 = cp;
s2 = (char *)str2;
while (*s1 && *s2 && !(*s1 - *s2))
s1++, s2++;
if (!*s2)
return(cp);
cp++;
}
return(NULL);
}
char * my_strchr(const char * string,int ch)
{
while (*string && *string != (char)ch)
string++;
if (*string == (char)ch)
return((char *)string);
return(NULL);
}
strlen
size_t my_strlen(const char * str)
{
const char *eos = str;
while (*eos++ != '\0')
;
//此时eos的位置在\0后面
return(eos - str - 1);
}