C语言--字符串几种库函数的模拟实现

       前言

            心向秃又强!!!


目录

       strlen函数

                分析:

                实现: 三种实现方式

       strcpy函数

                分析: 

                实现: 

       strcat函数       

                分析:

                实现:

       strcmp函数

                分析:

                实现: 

       strstr函数

                分析: 

                实现: 


       strlen函数
                分析:

                        1, 统计字符串的长度, "\0"为唯一结束标记, 要注意防止越界;

                        2, 形参为字符指针; 

                        3, 返回值为size_t, 无符号整形;

                        4, 对其断言assert, 防止传过来空指针;

                实现: 三种实现方式

                       

//模拟实现strlen
//方法一: 普通循环实现
size_t my_strlen1(char* str)
{
	int count = 0;
	assert(str);  //头文件为<assert.h>
	while (*str++)
	{
		count++;
	}
	return count;
}
//方法二: 递归实现
size_t my_strlen2(char* str)
{
	if (!*str)
		return 0;
	else
		return 1 + my_strlen2(str + 1);//注意这里不能用++,因为递归还要退栈,所以指针str不能改变指向,
}
//方法三: 指针 - 指针 
size_t my_strlen3(char* str)
{
	char* p = str;
	while (*p) //这里使用后置++的话,会多循环一次, 至于为什么, 看我博客 while循环后置++的判断细节
	{
		p++;
	}
	return p - str;
}

int main()
{
	char arr[] = { "abcdef" };
	printf("%d", my_strlen3(arr));

	
	return 0;
}

               


       strcpy函数
                分析: 

                        1, 拷贝字符串,  参数为两个指针, (char* dest, const char* str), 第一个指向目标字符串, 第二个指向源字符串;

                        2, 注意参数顺序, 将str空间的字符拷贝到dest中, 这里const修饰指针str指向的内容,是不希望其指向的内容被修改; 保证代码的健壮性. 

                        3, 循环拷贝, 以str指向\0为结束条件, 需要注意的是, \0也要拷贝到dest当中去, 使用while循环,就可以考虑在判断条件中使用后置++;

                        4, 函数的返回值为char* , 并且是目标空间dest的起始指针, 所以需要在一开始,保存起始指针;

                实现: 

                

//strcpy库函数的模拟实现
char* my_strcpy(char* dest, const char* str)
{
	char* ret = dest;
	assert(dest && str);
	while (*dest++ = *str++)
	{
		;
	}
	return ret;
}

int main()
{
	char arr1[10] = { "abcdef" };
	char arr2[10] = { 0 };
	
	printf("%s", my_strcpy(arr2, arr1));

	return 0;
}


       strcat函数       
                分析:

                        1, 追加字符串, 参数为两个指针, 第一个指向目标字符串, 第二个指向源字符串, 考虑const修饰;

                        2, 返回值为 目标空间的起始地址, 需要在一开始就保存起始地址;

                        3, assert断言 保证用户没有传递空指针;

                        4, 需要先找到目标字符串的末位\0, 再追加字符串, 需要保证目标空间足够大;

                        5, 也会将源字符串中的\0追加过去;

                实现:

                

//strcat函数的模拟实现
char* my_strcat(char* dest, const char* str)
{
	char* ret = dest;
	assert(dest && str);
	while (*dest)
	{
		dest++;
	}
	while (*dest++ = *str++)
	{
		;
	}
	return ret;
}

int main()
{
	char arr1[10] = { "abcdef" };
	char arr2[20] = { "acb"};
	
	printf("%s", my_strcat(arr2, arr1));

	return 0;
}


       strcmp函数
                分析:

                        1, 比较的是字符串的ASCLL值, 而不是长度;

                        2, 参数为两个指针, 分别指向两个字符串, 考虑用const修饰指针;     

                        3, 返回值为 大于0的数/ 0/ 小于0的数, 这里我们设置为1/ 0/ -1;

                        4, 断言assert, 防止用户传递空指针;

                实现: 

                

//strcmp函数模拟实现
int my_strcmp(const char* str1, const char* str2)
{
	int ret = 0;
	assert(str1 && str2);
	while (!(ret = *str1 - *str2) && *str1 && *str2)
	{
		str1++;
		str2++;
	}
	if (ret < 0)
		ret = -1;
	else if (ret > 0)
		ret = 1;
	
	return ret;
}

int main()
{
	char arr1[10] = { "abcdef" };
	char arr2[20] = { "aab" };
	int ret = my_strcmp(arr1, arr2);
	printf("%d \n", ret);

	return 0;
}


       strstr函数
                分析: 

                        1, 查找子字符串, 需要保留每一次查找的初始位置, 以保证在字符串不同时,可以回到查找的起始位置, 从下一个字符继续查找;

                        2, 两个指针, 分别指向不同的字符, 考虑使用const修饰指针;

                        3, 若传递的子字符串的指针为空, 返回目标字符串的指针; 

                        4, 未找到则返回NULL;

                实现: 

                

//strstr函数模拟实现
char* my_strstr(const char* str1, const char* str2)
{
	char* cp = str1;
	char* s1, * s2;
	if (!*str2)
		return (char*)str1;
	while (*cp)
	{
		s1 = cp;
		s2 = (char*)str2;
		while (*s1 && s2 && !(*s1 - *s2))
		{
			s1++;
			s2++;
		}
		if (!*s2)
			return cp;
		cp++;
	}
	return (NULL);
}

int main()
{
	char arr1[10] = { "abcdef" };
	char arr2[20] = { "def" };
	
	printf("%s\n",my_strstr(arr1, arr2));

	return 0;
}

       


        我是专注学习的章鱼哥~

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值