初识C语言:3.字符串函数

  1. strlen

1.定义

这是只针对字符串的计数功能函数,它用来统计\0之前的字符个数,返回值为int

目前所学有三种方法可以实现该函数的模拟:1.循环计数方法 2.递归方法 3.指针运算方法

2.模拟实现

1.循环计数

int my_strlen(const char* a)
{
    int count = 0;
    while (*a != 0)
    {
        count++;
        a++;
    }
    return count;
}

2.递归

int my_strlen(const char* str)
{
    if (*str != '\0')
    {
        return 1 + my_strlen(str + 1);
    }
    else if (*str == '\0')
    {
        return 0;
    }
}

3.指针运算

int my_strlen(const char* str)
{
    char* ret = str;
    while (*str != '\0')
    {
        str++;
    }
    return str - ret;
}

3.区别strlen与sizeof

  1. strlen是函数,而sizeof是操作符

  1. sizeof统计的是目标所在的空间大小,而strlen只统计字符个数

  1. sizeof可以计算整型数组,字符串,结构体等空间,而strlen只能计算字符串4

  1. strcpy

1.定义

将来源字符串拷贝到目标字符串的后面,将目标字符串的\0变为来源字符串的首字符,并将来源字符串结尾的\0也拷贝到目标字符串中。返回目标字符串的首地址

2.模拟实现

char* my_strcpy( char* des,const char* src)
{
    char* ret = des;
    assert(des && src);
    while (*src!='\0')
    {
        *des++=*src++;
    }
    return ret;
}
  1. strcat

1.定义

这个函数的功能是给目标字符串的第一个\0处追加一个来源字符串。来源字符串的第一个\0同样被追加过去。

2.模拟实现

char* my_strcat(char* des, const char* src)
{
    char* ret = des;
    while (*des != '\0')
    {
        des++;//找到目标字符串的第一个'\0'
    }
    while (*src != '\0')
    {
        *des ++= *src++;
    }
    *des++ = *src++;

    return ret;
}

3.同一字符串不能自我追加

因为将来源字符串的第一个字符赋给目标字符串的\0时,由于目标和来源是同一个字符串,其实把来源字符串的\0覆盖了,导致该函数无法找到来源字符串的\0以结束

  1. strstr

1.定义

这个函数的功能是在一个大字符串中找到含有小字符串的部分,并返回这部分的初始指针。

2.模拟实现

char* my_strstr(const char* des, const char* src)
{
    char* s1 = des;
    char* s2 = src;
    char* s3 = s1;//s3是作为初始位置的一个记录
    while (s1!='\0')
    {
        if (*s1 == *s2)
        {
            s1++;
            s2++;
            if (*s2 == '\0')//当来源字符串都找完了,还没有跳出,说明找到了
            {
                return s3;
            }
        }
        else if (*s1 != *s2)
        {
            s1 = s3 + 1;//将下次开始寻找的初始位置回退到上次开始寻找的位置的下一位
            s2 = src;//来源字符串的指针每次重新寻找都要回退到首字符
            s3++;//s3作为s1的记录自然也要进到下一位
        }
        
    }
    return NULL;
}

5.strtok

char* strtok(char* str,const char* sep)

1.定义

sep是使用者想要定义作为分割符的字符合集。

strtok会将来源字符串切分成一段一段的,会破坏原有的字符串,所以最好先将原有字符串进行拷贝。

如果第一个参数不为NULL,strtok会从参数的头部开始找到第一个标记,并返回切分的字符串地址,同时,strtok函数会在内部保存标记的地址;当strtok第一个参数为NULL时,strtok函数会从同一字符串被保存的位置开始查找下一个标记。

2.使用

int main()
{
    char s[] = "1209722997@qq.com.cn";
    char copy[30] = { 0 };
    my_copy(copy, s);
    char* str = NULL;
    const char sep[] = "@.";
    for (str = strtok(copy, sep); str != NULL;str= strtok(NULL, sep))
    {
        printf("%s\n", str);
    }
    return 0;
}

3.注意

这个函数有记忆保存功能,即使在使用结束后,它还会保存上一次使用的时候,找到的标记的位置

6.内存函数memcpy memmove

  1. 定义

void* memmove(void* destination, const void* source, size_t num)
  • memcpy和memmove功能类似,这里主要学习memmove

  • 这个函数的功能是将源内存块向后的num个字节复制到目标内存块中。memcpy 和memmove的区别是memmove的源内存块和目标内存块是可以重叠的

  • 由于是以字节为单位复制,且不知道要移动的数据是什么类型的数据,所以形参定义为void* 类型,方便接收各种类型的数据,也方便转换为char* 类型

  1. 模拟实现

总体思路就是先将重叠部分的字节拷贝,防止被覆盖。这个思路决定从前向后或是从后向前的拷贝顺序。

void my_memmove(void* des, const void* src, size_t n)
{
    if (src < des)
    {
        while (n--)
        {
            *((char*)des+n) = *((char*)src+n);
        }
    }
    else if (des < src)
    {
        while (n--)
        {
            *(char*)des = *(char*)src;
            des = (char*)des + 1;
            src = (char*)src + 1;
        }
    }
}

7.memcmp

  1. 定义

int memcmp(const void* ptr1,const void* ptr1,size_t num)

比较ptr1和ptr2指针开始的num个字节

2.模拟实现

int my_memcmp(const void* p1, const void* p2, size_t n)
{
    assert(p1 && p2);
    while (*(char*)p1 == *(char*)p2)
    {
        p1 = (char*)p1 + 1;
        p2 = (char*)p2 + 1;
    }
    return *(char*)p1 - *(char*)p2;
}

3.注意事项

由于是以字节为单位进行比较,所以根据大小端存储的不同,结果可能会不同

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值