1、memcpy
面试中如问到memcpy的实现,那就要小心了,这里有陷阱。
先看下标准memcpy()的解释:
void *memcpy(void *dst, const void *src, size_t n);
//If copying takes place between objects that overlap, the behavior is undefined.
注意下面的注释,对于地址重叠的情况,该函数的行为是未定义的。
事实上所说的陷阱也在于此,自己动手实现memcpy()时就需要考虑地址重叠的情况。
另外,标准库也提供了地址重叠时的内存拷贝函数:memmove(),那么为什么还要考虑重写memcpy()函数呢?
因为memmove()函数的实现效率问题,该函数把源字符串拷贝到临时buf里,然后再从临时buf里写到目的地址,增加了一次不必要的开销。
void* memcpy(void *dst, const void *src, size_t count)
{
//安全检查
assert( (dst != NULL) && (src != NULL) );
char *pdst = (char *)dst;
const char *psrc = (const char *)src;
//防止内存重复
assert(!(psrc<=pdst && pdst<psrc+count));
assert(!(pdst<=psrc && psrc<pdst+count));
while(count--)
{
*pdst++ = *psrc++;
}
return dst;
}
2、strcpy
标准库声明:char *strcpy(char *dest, const char *src);
char * strcpy( char *dest, const char *src )
{
assert( (dest != NULL) && (src != NULL) );
if(dest == src)
return dest;
char *ptr = dest;
while( (*dest++ = * src++) != '\0' )
;
return ptr;
}
3、strncpy
标准库声明:char *strncpy(char *dest, const char *src, size_t n);
char *strncpy(char *dest, const char *src, size_t count)
{
assert(dest != NULL && src != NULL);
char *ptr = dest;
while (count-- && *src != '\0')
*dest++ = *src++;
*dest = '\0';
return ptr;
}
4、strstr
标准库声明:char *strstr(const char *haystack, const char *needle);
char *strStr(char *haystack, char *needle)
{
// IMPORTANT: Please reset any member data you declared, as
// the same Solution instance will be reused for each test case.
if(needle == NULL || haystack == NULL)
return NULL;
int i,j;
for (i = j = 0; haystack[i] && needle[j];)
{
if (haystack[i] == needle[j])
{
++i;
++j;
}
else
{
i = i - j + 1;
j = 0;
}
}
return needle[j]?NULL:(haystack + i - j);
}
5、memmove
标准库声明:void *memmove(void *dest, const void *src, size_t n);
void* memmove(void* dst,const void* src,size_t n)
{
assert(dst != NULL && src != NULL);
char* p = (char*)dst;
char* q = (char*)src;
if (p <= q || p >= q + n)//
{
while (n--)
{
*p++ = *q++; //按递增拷贝
}
}
else //
{
p += n -1;//overlap的情况,从高位地址向低位拷贝
q += n -1;
while (n--)
{
*p-- = *q--; //按递减拷贝
}
}
return dst;
}
6、strcmp
int strcmp(const char *s, const char *t)
{
assert(s != NULL && t != NULL);
while (*s && *t && *s == *t)
{
++ s;
++ t;
}
return (*s - *t);
}
7、strlen
size_t strlen(const char *str)
{
assert(str != NULL);
const char *s = str;
while(*s != '\0')
s++;
return(s - str);
}
8、strcat
char *strcat(char *dst, const char *src)
{
assert((dst != NULL) && (src != NULL));
char *pdst = dst;
while (*dst != '\0')
++dst;
while ((*dst++ = *src++) != '\0')
;
return pdst;
}