模拟实现字符串函数(strlen strcat strcpy strcmp strstr )

strlen的三种模拟实现方式

strlen的参数设计思路:
由于直到长度是不可能为负数,所有返回值设计为 size_t;
由于所求的字符串不可能要修改,所以加const 修饰形参str;

计数器方式模拟实现strlen

size_t my_strlen(const char* str)
{
	int count = 0; //统计字符串长度
	while(*str != '\0')
	{
		count++;
		str++;
	}
	//退出循环后,表示到了\0位置
	return count;
}

说一说一些设计小细节:

我们这里直接用 str 字符串指针去移动了,为什么不设计一个指针cur直接指向str字符串,让这个cur去移动呢?

很好理解,因为我们函数本来就是要求字符串长度的,并不去要保存str字符串的首地址,所以不需要而外的变量去指向str,直接用str移动更好。


指针-指针的方式实现strlen

size_t my_strlen( const char* str)
{
	 const char* first = str;
	 const char* end = str;
	while(*end != '\0')
	{
		end++;
	}
	//退出循环后 end指向了 \0
	return first - endl; //指针 - 指针表示距离
}

递归的方式实现 strlen

递归思想很简单:求大问题化成小问题就行,不要死磕递归的所有过程,因为很容易陷入进去出不来,我们要注重递归的大致方向就行。
比如递归实现strlen,首先明确strlen函数功能求字符串函数长度,那么用递归思想就是求字符串的长度,就可以求出第一个字符串长度+加上接下来第二个起步的剩下的字符串串长度即可。

size_t my_strlen(const char* str)
{
	//递归结束条件 
	if(*str == '\0') return 0;
	//来到这里说明*str 不等于\0,那就求字符串长度
	return 1 + my_strlen(++str);
}

这个方式求字符串长度的好处就是简单,代码简洁,并且还可以不创建临时变量就可以统计出字符串长度咯


strcat模拟实现

字符串追加模拟实现思路:

找到目标字符串的\0位置,把源字符串拷贝到目标字符串的地方去,直到拷贝完源字符串,同\0也拷贝过去。

char* my_strcat(char* destination,const char* source)//向destination追加source
{
	char* temp = destination;//用于保存目的地字符串的首地址,方便返回
	while(*destination != '\0')
	{
		destination++;
	}
	//来到这里说明destination到了\0的位置
	//此时将源字符串source追加
	while(*source !='\0')
	{
		*destination = *source;
		destination++;
		source++;
	}
	//来到这里说明source == '\0'
	*destination = *source;
	
	return temp;
}
*********************************************************************
*********************************************************************
*********************************************************************
//当然上面的代码还可以精简
char* my_strcat(char* destination,const char* source)//向destination追加source
{
	char* temp = destination;//用于保存目的地字符串的首地址,方便返回
	while(*destination++){ ; }
	
	//来到这里说明destination到了\0的位置
	//此时将源字符串source追加
	while(*destination++ = *source++){ ; }
	return temp;
}


strcpy模拟实现

思路:源字符串遇到\0就表示拷贝结束了,那么就可以抓这个点去思考。

char* my_strcpy(char* destination,const char* source)//将source拷贝到destination中
{
	char* temp = destination; //用于保存目的地字符串的首地址,方便返回
	assert(destination && source);//断言一下,空指针直接报错
	while( *source != '\0')
	{
		*dstination = * source;
		destination++;
		source++;
	}
	//退出循环后表示 源字符全部拷贝过去
	*dstination = * source;
	return temp;
}
______________________________________________________________
//有一种比较精简的写法
char* my_strcpy(char* destination,const char* source)//将source拷贝到destination中
{
	char* temp = destination; //用于保存目的地字符串的首地址,方便返回
	assert(destination && source);//断言一下,空指针直接报错
	while(*destination++ = *source++) { ; }	
	//退出循环后表示 源字符全部拷贝过去
	return temp;
}

strcmp模拟实现

字符串比较的实现思路:
抓住对应字符的比较,当不相等时候就直接返回>0或者<0的情况;
和相等的前提下先遇到\0就表示字符串相等且匹配结束,没遇到\0就继续遍历匹配。

int my_strcmp(const char* str1,const char* str2)
{
	while(*str1 == *str2)
	{
		//在相等的前提下,只要有一个字符是 \0,就表示匹配结束,于此同时两个字符串相等返回0
		//下面一句代码等价if(*str1) return 0; 或者 if(*str2) return 0;
		if(*str1 =='\0'|| *str2 == '\0') return 0; 
		
		//相等的前提下,且*str1和*str2字符不等\0,继续前进
		str1++;
		str2++;		
	}
	//到这里说明来个字符串不等
	//返回对应字符相减得到的是十进制的数字,大于0和小于0 的情况都包含了
	return *str1 - *str2;
}

strstr模拟实现

strstr查找字符串子串函数,模拟实现的主要思路:
查找到子串,返回的是子串在主串的首地址;
当两个字符串相等时候就一直往前走;前提必须是主串和子串还没到\0;
不相等时候主串就回到原来位置的下一位,子串就回到原来的位置;

char* my_strstr(const char* str1,const char* str2)//在str1查找子串str2
{
	const char* pStr1 ;
	const char* pStr2;
	const char* pre = str1;

	while(*pre !='\0')
	{
		pStr1 = pre; //pStr1指向pre
		pStr2 = str2;//pStr2指向str2的首地址
		while(*pStr1 == *pStr2 && *pStr1 != '\0' && pStr2 != '\0') //当两字符相等时候
										//且还没匹配结束,即主串和子串都还能到\0时候			
		{
			//在*pStr1 == *pStr2前提下,pStr1往前走	pStr2往前走		
			pStr1++;
			pStr2++;
		}
		//退出循环后,把*pStr2 == '\0'拦截下来,因为表示匹配结束了
		if(*pStr2 == '\0') return pre;
		
		//当pStr1 != pStr2时候,pre+1
		//为的是,在pStr1 != pStr2时候,pStr1能够找回原来位置的下一个位置
		pre++;
	}
	//退出while(*pre !='\0')表示匹配失败
	return NULL;
}

其实这就是一种BF算法,最简单的字符串匹配算法,对应的还有KMP算法呢。但是这里不打算说KMP有兴趣可以去搜一搜。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

呋喃吖

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值