0
点赞
收藏
分享

微信扫一扫

strlen与strcpy解析+模拟实现

strlen -求字符串长度的库函数

image.png

坑点:返回类型是size_t      (sizeof返回类型也是size_t)
  • 字符串以\0为结束标志,strlen()函数返回的是在字符串中‘\0’前面出现的字符个数(不包含\0)

  • 参数指向的字符串必须要以\0结尾

    char arr[] = {'a','b','c'};
    strlen(arr);  //err
  • 函数的返回类型为size_t,是无符号数
int main()
{
    const char* str1 = "abcdef";
    const char* str2 = "abc";
    if (strlen(str2) - strlen(str1) > 0)
    {
        printf("str2 > str1\n");
    }
    else
        printf("str2 < str1\n");
    return 0;
}

打印结果:str2>str1

原因:strlen返回的是无符号数, 3 - 6 = -3被认为是无符号数,将-3对应的补码直接转化为十进制,得出的值>0

strlen()的模拟实现

方法1:计数器

size_t  my_strlen(const char* str)
{
    size_t count = 0;
    while (*str)
    {
        count++;
        str++;
    }
    return count;
}
int main()
{
    char* str = "Mango";
    size_t count = my_strlen(str);
    printf("%u\n", count);
    return 0;
}

方法2:指针-指针

指针-指针->得到的是二者相差的元素的个数

一个尾指针指向\0,一个指向起始位置,二者相减得到的就是字符串长度

size_t my_strlen(const char* str)
{
    const char* start = str;
    const char* end = str;
    while (*end)
    {
        end++;
    }
    return end - start;
}
int main()
{
    char* str = "Mango";
    size_t count = my_strlen(str);
    printf("%u\n", count);
    return 0;
}

方法3:递归

size_t my_strlen(const char* str)
{
    //如果指向的不是\0,就+1(本身指向的字符),然后递归下一个字符
    if (*str)
    {
        return 1 + my_strlen(str + 1);
    }
    //str指向的是\0就返回0
    else
    {
        return 0;
    }
}
int main()
{
    char* str = "Mango";
    size_t count = my_strlen(str);
    printf("%u\n", count);
    return 0;
}

strcpy-字符串拷贝函数

image.png

int main()
{
    char arr1[] = "xxxxxxxx";
    char arr2[] = "hello";
    strcpy(arr1,arr2);
    printf("%s\n",arr1);
    return 0;
}

打印结果:hello

注意:arr2中的\0也拷贝了过去

int main()
{
    char arr1[] = "xxxxxxxx";
    char arr2[] = "he\0llo";
    strcpy(arr1,arr2);
    printf("%s\n",arr1);
    return 0;
}

打印结果:he

注意:如果arr对应字符串中提前有\0,则只拷贝\0之前的内容

strcpy:拷贝的是源字符串开始向后直到\0前的内容

  • 源字符串必须以\0结束

    char arr2[] = {'a','b','c'};
    char arr1[] = "xxxxxxx";
    strcpy(arr1,arr2);    //err
  • 会将源字符串的\0拷贝到目标空间
  • 目标空间必须足够大,以确保能存放源字符串

    char arr1[] = "xxx";
    char arr2[] = "hello\0abc";
    strcpy(arr1,arr2);    //err
    //原因:arr1的大小为4,根据后面初始化的内存缺点arr1的大小,空间太小,不足以存放arr2中\0之前的内容
  • 目标空间必须可变

    const char* p = "xxxxxxx";
    char arr2[] = "hello\0abc";
    strcpy(p,arr2);   //err
    //p为常量字符串不可以修改

模拟实现strcpy

注意点:源字符串不修改,所以用const修饰,返回类型为char*,返回的是目标空间的起始地址,所以定义一个指针保存起始地址,然后将src指向的内容拷贝到dest中

char* my_strcpy(char* dest,const char* src)
{
    assert(dest&&src);
    char* ret = dest;   //保存起始地址
    while(*src)
    {
        *dest = *src;
        dest++;
        src++;       
    }
    //上述只是完成了将src中\0之前的内容拷贝
    //还要拷贝\0
    *dest = *src;
    return ret;
}
int main()
{
    char arr1[] = "xxxxxxx";
    char arr2[] = "Mango";
    char* ret = my_strcpy(arr1,arr2);
    printf("%s\n",arr1);
    printf("%s\n",ret);
    return 0;
}
举报

相关推荐

0 条评论