模拟实现字符串函数及内存函数

模拟实现strstr函数

strstr函数的功能是模式匹配。

实现my_strstr函数,首先确定函数的参数是两个字符串的地址,函数返回值类型也是一个地址

char* my_strstr(const char *str1,const char *str2)
{

定义s来接受主串str1的地址,定义t来接受模式串str2的地址

    const char *s = str1;//主串
    const char *t = str2;//模式串

定义i为主串的下标,j为模式串的下标,进行分析:当主串第一个字符和模式串第一个字符相等时,i和j同时加1,然后比较第二个字符,以此类推。直至遇见两个不同的字符,此时要把模式串与主串中的第二个字符重新开始比较,即j=0,i=i-j+1

    int i, j;
    i = j = 0;
    while (s[i]!='\0'&&t[j]!='\0')
    {
        if (s[i] == t[j])
        {
            i++;
            j++;
        }
        else
        {
            j = 0;
            i = i - j + 1;
        }
    }

最后还要进行判断,如果是t[j]=='\0',则返回字符串,否则的话,一定是主串先一步结束,即主串中不包含模式串,那么就返回NULL

    if (t[j] == '\0')
    {
        return s+i-j;
    }
    return NULL;
}

模拟实现strcat函数

strcat函数的功能是连接字符串

char *my_strcat(char *strDest,const char *strSrc)//模拟实现strcat函数
{
    char *str1 = strDest;//定义str1指向目标字符串的地址
    assert(strDest != NULL && strSrc != NULL);
    while (*str1 != '\0')
    {
        str1++;
    }//str1指向该字符串'\0'的位置
    while (*strSrc!='\0')
    {
        *str1++ = *strSrc++;
    }
    return strDest;
}

模拟实现strcmp函数

strcmp函数功能是比较两个字符串对应位置的字符的ASCLL码

char *my_strcpy(char *strDest,const char *strSrc)//模拟实现strcpy函数
{
    assert(strDest!=NULL&&strSrc!=NULL);
    char *str1 = strDest;
    const char *str2 = strSrc;
    while (*str2!='\0')
    {
        *str1++ = *str2++;
    }
    *str1 = '\0';
    return strDest;
}

模拟实现strlen

计算字符串长度

size_t my_strlen(const  char *str)//模拟实现strlen
{
    assert(str!=NULL);
    const char *strEnd = str;
    while (*strEnd!='\0')
    {
        strEnd++;
    }
    return strEnd - str;
}

模拟实现memset函数

memset函数功能是对一片内存空间进行初始化

/*memset函数按字节对内存块进行初始化,
所以不能用它将int数组初始化为0和-1之外的其他值(除非该值高字节和低字节相同)*/
void *my_memset(void *dest, int n, size_t count)//模拟实现memset函数
{
    assert(dest!=NULL);
    char *pdest = (char*)dest;//强转是为了一次只操作一个字节
    while (count--!=0)
    {
        *pdest++ = n;
    }
    return dest;
}

模拟实现memcpy函数

memcpy函数功能是将一片内存空间里的数据复制给另一片内存空间,但如果发生内存重叠就无法解决,需要使用memmove函数

//'\0'也会被拷贝
void *my_memcpy(void *strDest,const void *strSrc,size_t count)//模拟实现memcpy函数
{
    char *str1 =(char*)strDest;
    char *str2 = (char*)strSrc;
    assert(strDest != NULL);
    while (count--!=0)
    {
        *str1++ = *str2++;
    }
    return strDest;
}

模拟实现memmove函数

与memcoy函数功能相似,可以解决内存重叠问题

void *my_memmove(void *strDest, const void *strSrc, size_t count)//模拟实现memmove函数
{
    assert(strDest!=NULL&&strSrc!=NULL);
    char *str1 =(char *) strDest;
    const char *str2 = (char *)strSrc;
    //1.源地址只要大于目标地址,从后面的空间往前复制数据,不会有影响
    //2.目标数组在源数组整体之后,即目标地址大于原地址+原数组元素个数,数据也可以照常复制
    if (str2>=str1||str1>=str2+count)
    {
        while (count-- != 0)  
        {
            *str1++ = *str2++;
        }
    }
    //目标地址与原地址发生内存重叠,即:目标数组的初始N个元素就是源数组的末尾N个元素,如果从源数组的开头进行复制,到结尾时,末尾N个元素的值就已经被修改了。
    //解决方案:从源数组的末尾往前进行数据复制
    else
    {
        str1 = str1 + count-1;
        str2 = str2 + count-1;
        while (count-- != 0)
        {
            *str1-- = *str2--;
        }
    }
    return strDest;
}
上一篇:string,特殊的引用类型


下一篇:理顺 JavaScript (20) - String 中的正则表达式函数