07库函数编写

来源:互联网 发布:qq聊天软件 编辑:程序博客网 时间:2024/05/16 07:03

1:字符串查找

        给定一个字符串A,要求在A中查找一个子串B。如A="ABCDF",要你在A中查找子串B=“CD”。

 

        初步代码如下:

int  strstr(char *string, char *substring)     

{    

    if (string == NULL|| substring == NULL)       

        return -1;       

     

    int  lenstr = strlen(string);    

    int  lensub= strlen(substring);    

     

    if (lenstr < lensub)       

        return -1;        

     

    int len = lenstr - lensub; 

    for (int i = 0; i <= len; i++)   //复杂度为O(m*n)   

    {    

        for (int j = 0; j < lensub; j++)     

        {    

            if (string[i+j] !=substring[j])    

                break;    

        }    

        if (j == lensub)    

            return i + 1;    

    }    

    return -1;    


        针对这个strstr的函数,我觉得有点小问题。我查了一下C标准库的源码,它给的声明是这样的,两个参数都有const

char *strstr(const char *haystack_start, const char *needle_start)

        而且标准库中没有调用strlen函数,因为假如你是标准库的设计者,strlen()函数还没设计出来,你怎么去计算两个字符串的长度?是不是只能通过指针移动来实现,我觉得这些都是微软要考察的地方。

        此外:还有int lenstr=strlen(string);这是不安全的?strlen函数的返回类型是size_t型,也就是无符号整型,假如我的数组长度很长(假如是用堆分配的,可以很大很大),长过2的31次方减1的话,会发生一处,你这lenstr就会变成负值了,所以用size_t类型最保险。

 

2:字符查找

        在一个字符串中找到第一个只出现一次的字符。如输入abaccdeff,则输出b。代码如下:

char  FirstNotRepeatChar(char  * pString)    

{    

    if(!pString)    return '\0';    

     

    const  int  tableSize = 256;   

    int   hashTable[tableSize] = {0};     //存入数组,并初始化为0    

     

    char  * pHashKey = pString;    

    while(*(pHashKey) != '/0')    

        hashTable[*(pHashKey++)]++;    

      

    while(*pString != '/0')    

    {    

        if(hashTable[*pString] == 1)    

            return   *pString;    

         

        pString++;    

    }    

    return '\0';  //没有找到满足条件的字符,退出    

 

3:字符串拷贝
    题目描述:要求实现库函数strcpy,

    原型声明:extern  char*strcpy(char *dest,char *src);
    功能:把src所指由NULL结束的字符串复制到dest所指的数组中。  
    说明:src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。返回指向dest的指针。

    分析:如果编写一个标准strcpy函数的总分值为10,下面给出几个不同得分的答案:

    //2分 

    void  strcpy( char *strDest, char *strSrc) 

    {  

        while( (*strDest++ = * strSrc++) !='/0' ); 

    }  

     

    //4分 

    void  strcpy( char *strDest, const char *strSrc )  

    { 

        //将源字符串加const,表明其为输入参数,加2 

        while( (*strDest++ = * strSrc++) !='/0' ); 

    }  

     

    //7分 

    void  strcpy(char *strDest, const char *strSrc)  

    { 

        //对源地址和目的地址加非0断言,加3 

        assert((strDest != NULL) && (strSrc != NULL) ); 

        while( (*strDest++ = * strSrc++) !='/0' ); 

    }  

     

    //10分 

    //为了实现链式操作,将目的地址返回,加3分! 

    char * strcpy( char *strDest, const char *strSrc )  

    { 

        assert((strDest != NULL) && (strSrc != NULL) ); 

        char *address =strDest;  

        while( (*strDest++ = * strSrc++) !='/0' );  

        return address; 

}  

 

4:部分库函数的实现

char  *strncpy(char  *strDes, const char *strSrc,  unsigned  int  count)     

{     

    assert(strDes !=NULL && strSrc != NULL);     

    char *address = strDes;     

    while (count--&& *strSrc != '\0')     

        *strDes++ = *strSrc++;  

    *strDes = '\0'; 

    return  address;     

}  

 

//查找字符串s中首次出现字符c的位置  

char  *strchr(const  char *str, int  c)  

{  

    assert(str !=NULL);  

    for (; *str != (char)c; ++ str)  

        if (*str == '\0')  

            return NULL;  

    return str;  

}  

 

int  strcmp(const char *s, const char *t)  

{  

    assert(s != NULL&& t != NULL);  

    while (*s&& *t && *s == *t)  

    {  

        ++ s;  

        ++ t;  

    }  

    return (*s -*t);  

}  

int  strncmp(constchar *s, constchar *t, unsigned int count)  

{  

    assert((s != NULL) && (t !=NULL));  

    while (*s && *t && *s == *t&& count --)  

    {  

        ++ s;  

        ++ t;  

    }  

    return (*s - *t);  

}

 

char  *strcat(char *strDes, const char *strSrc)  

{  

    assert((strDes != NULL) && (strSrc!= NULL));  

    char *address = strDes;  

    while (*strDes !='/0')  

        ++ strDes;  

    while ((*strDes ++= *strSrc ++) != '/0')  

        NULL;  

    return address;  

}  

char   *strncat(char *strDes, const char *strSrc,unsigned int count)  

{  

    assert((strDes != NULL) && (strSrc!= NULL));  

    char *address = strDes;  

    while (*strDes !='/0')  

        ++ strDes;  

 

    while (count --&& *strSrc != '/0' )  

        *strDes ++ =*strSrc ++;  

    *strDes = '/0';  

 

    return address;  

}

 

int  strlen(constchar *str)  

{  

    assert(str !=NULL);  

    int len = 0;  

    while (*str ++ != ‘\0’)  

        ++ len;  

    return len;  

}  

 

//将字符串拷贝到新的位置    

char  *strdup_(char *strSrc)    

{    

    if(strSrc!=NULL)    

    {    

        char *start=strSrc;    

        int len=0;    

        while(*strSrc++!='/0')    

            len++;    

         

        char *address=(char*)malloc(len+1);    

        assert(address!= NULL); 

         

       while((*address++=*start++)!='/0');     

        return address-(len+1);     

    }    

    return NULL;    

}    

 

char  *strstr(const char *strSrc, const char *str)

{  

    assert(strSrc !=NULL && str != NULL);  

    const char *s = strSrc;  

    const char *t = str;  

    for (; *strSrc != '\0';++ strSrc)  

    {  

        for (s = strSrc,t = str; *t != '\0' && *s ==*t; ++s, ++t)  

            NULL;  

        if (*t == '\0')  

            return (char *) strSrc;  

    }  

    return NULL;  

}  

 

/*  功能:依次检验字符串s1中的字符,当被检验字符在字符串s2中也包含时,则停止检验,并返回该字符位置,空字符NULL不包括在内。*/

char  *strpbrk(constchar *strSrc, const char*str)  

{  

    assert((strSrc !=NULL) && (str != NULL));  

    const char *s;  

    while (*strSrc != '\0')  

    {  

        s = str;  

        while (*s != '\0')  

        {  

            if (*strSrc == *s)  

                return (char *) strSrc;  

            ++ s;  

        }  

        ++ strSrc;  

    }  

    return NULL;  

}  

 

void  *memcpy(void *dest, const void *src, unsigned int count)  

{  

    assert((dest !=NULL) && (src != NULL));  

    void *address = dest;  

    while (count --)  

    {  

        *(char *) dest= *(char *) src;  

        dest = (char *)dest + 1;  

        src = (char *)src + 1;  

    }  

    return address;  

}  

 

5:总结

       1:判断指针参数是否为NULL

       2:如果参数只读不写,则需要添加const

       3:函数中尽量不要调用其他库函数

       4:申请内存后,需要判断是否申请成功

       5:如果是内存函数,则注意指针类型

 

http://blog.csdn.net/v_JULY_v/article/details/6417600

0 0
原创粉丝点击