标准库函数实现

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;
}










评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值