用c语言实现库函数——字符串函数strcat,strcmp

发布时间:2023年12月30日

学习使用库函数是我们学习c语言必须掌握的,不会灵活使用库函数是一个不太合格的码农。当然库函数也是函数,我们只需要了解怎么使用就行。但是总有人想要知道这些库函数是这么实现的。当然了接下来我就介绍几个有关字符串有关的库函数。希望对你们有帮助吧,

我要讲解字符串有关的库函数,说倒字符串大家都不会陌生的,那接看一下这两个代码

char arr1 = "happy new year";
char arr2 = "to you all "

大家看见这两个字符数组,不难发现怎么将两个字符数组元素组在一起尼,组在一起就是祝福大家快新的一年快乐,比较大家都放元旦假了,就我一个人这个时候不忘记分享一下知识给你们,好了废话都不多了。这个时候就要借助我们 好工具——库函数 (strcat);这个库函数作用是把arr2的数组元素追加倒arr1的屁股后面当“小弟”;当然也可以将arr1 变成arr2的小弟也不是不可以,这个时候就是你这个老大想怎么做了。只需要改变参数位置就ok了。当然了也不是谁都能让当小弟了,这个时候就有人会说这个是怎么讲的,这个函数还是有不足地方,比如我要arr2追加倒arr1后面,假如arr1只能装不下arr2的元素就会出现缓冲区溢出问题。所以说我们要注意追加(目标函数)能够存的下去,当然除了缓冲区溢出问题还有空指针啊,还有字符串终止符等;像我们字符串函数都会运用字符串这个隐藏终止符 ——“\0”;我们想要arr2当小弟,跟着大哥后面总要找到大哥最后一个位置吧,然后在进行拷贝替换,就会有人问既然是追加,为什么到这里就说成替换尼,我来解释一下因为假如arr1有三十个字节,arr1元素假设占了十个字节,那还有剩下字节我是通过调试知道剩下的都是以0占的,以“\0”做终止标志,所以说我们想arr2元素追加到arr2后面本质是替换。当然你们也可以调试试试看。假如我哪里说的不对,欢迎你们指出来;那接下来看一下这个代码吧

char* my_strcat(char* p1, const char* p2)
{
	char* res = p1;//记录元素
	assert(p1 && p2);
	while (*p1)//找到arr1的/0的位置
	{
		 p1++;//指针指向/0但是不需要解引用,只需要指向就行
	}
	while ((*p1++ = *p2++))//将p1的/0与p2的元素进行解引用替换,当p2遇见/0,同时p1也是0就会退出循环,同时res也记录下来并返回
	{
		;
	}
	return res;
}
int main()
{
	char arr1[30] = "happy new year";
	char arr2[] = "to you all";
	my_strcat(arr1, arr2);
	printf("%s\n", arr1);
	return 0;
}

这里我是运用指针的方法的,接下来我来简单分析一下这串代码吧my_strcat函数接收两个参数,这个时候有人看见为什么是 const 修饰第二个参数,因为第一个参数要发生改变不能用const修饰

但是我们不希望第二个参数发生改变,所以用const修饰一下,然后我们看到assert(p1 && p2)这个作用是使用?assert?断言来确保?dest?和?src?均不为 NULL。然后第一个while循环(*p1)解引用p1然后在p1++这里只需要指针指向位置加1,不需要解引用,然后如此循环下去直到(*p1)解引用遇到“\0",然后退出循环同时指针p1指向arr的”\0“;然后进入第二个while循环(*p1++ = *p2++)等价于(*p1)++ = (*p2)++;先解引用在p1等于p2,然后指针加一,因为p1上面讲的一直是0,这个时候只要p2遇见”\0"就退出循环,while的括号里面逗好,即使不用也要加一个空语句。最后通过res记录,并返回,用arr1输出是因为执行了?my_strcat_recursive(arr1, arr2)?后,arr1?中的内容已经发生改变,变成了?"happy new year to you all",这是将?arr2?的内容连接到?arr1?后得到的结果。当然了这个只是其中一中方法模拟实现这一个函数。这里我就只介绍这一个指针方法。这里我就介绍这一中方法。

接下来就介绍第二个函数strcmp,续接上一个例子我们来看一下吧

char arr1 = "happy new year";
char arr2 = "to you all "

假如我们想要知道这两个字符数组谁大谁小尼,我们一看肯定有人会说arr1大啊,因为他的字符数比arr2多就大了。要是生活中可以怎么说,但是在这里我们不能怎么说,因为编译器在使用ASCII码进行字符比较的,相信学习编程人都听说过这个ASCll这个,所以说我们要把字符转化成ASCll的值进行比较,所以说两个字符数组一个一个上下对齐比较,相同就同时指向下一个字符进行比较。

这就是strcmp运行原理,接下来看代码吧,通过代码分析,这里我还是以指针的方法的

int my_strcmp(const char* p1, const char* p2)
{
    assert(p1 && p2);
    while (*p1 == *p2)
    {
        if (*p1 == '\0') {
            return 0;
        }
        p1++;
        p2++;
    }
    return *p1 - *p2;
}

int main()
{
    char arr1[30] ="happy new year";
	char arr2[] = "to you all";
    int res = my_strcmp(arr1, arr2);
    if (res > 0)
        printf("arr1 > arr2");
    else if (res < 0)
        printf("arr1 < arr2");
    else
        printf("arr1 = arr2");

    return 0;
}

这里我们就简单分析一下这个代码吧,通过my_strcmp接收参数,同时我们不希望这两个实参发生改变,我们保持一个好的习惯给用const修饰一下,同时给两个形参断言一下。,然后进入while判断*p1? 是否等于 *p2,假如等于就同时指针加一指向下一个在进行判断一下,假如遇见不相等,就两个解引用做差,并返回res接受判断大小,大于0就是arr1>arr2,反之小于0就是arr1<arr2 ,然后就是相等输出arr1 == arr2,if(*p1 == ”\0“)等价于if(*p1)这个作用是防止两个字符一直相等遇见”\0"都遇见”\0“;

好了这个两个函数就介绍到这了,当然了这两个函数都可以使用递归方法模拟实现,但是我这里就不简述递归过程了,你们看看一下就行了。我就在这个原来基础上稍微修该一下。看看就行了。

int my_strcmp(const char* p1, const char* p2)
{
    assert(p1 && p2);
    if (*p1 && *p2)
    {
        return 0;
    }

    if (*p1 == *p2) {
        // 如果当前字符相等,则比较下一个字符
        return my_strcmp(p1 + 1, p2 + 1);
    } else {
        // 如果当前字符不相等,则返回两个字符的差值
        return *p1 - *p2;
    }
}

int main()
{
    char arr1[30] ="happy new year";
    char arr2[] = "to you all";
    int res = my_strcmp(arr1, arr2);

    if (res > 0)
        printf("arr1 > arr2");
    else if (res < 0)
        printf("arr1 < arr2");
    else
        printf("arr1 = arr2");

    return 0;
}

文章来源:https://blog.csdn.net/pg19324843157/article/details/135298540
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。