关于字符串函数的模拟实现

字符串拷贝的函数模拟实现:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<assert.h>
#include<string.h>
char* my_strcpy(char*dest,const char*scr)//const表示指针指向的源字符串不能被改变
{
	 char* ret = dest;
     assert(dest != NULL);//断言
	 assert(scr != NULL);
	 while(*dest++ = *scr++)
	{
		;
	}
	return ret;//返回目标字符串的第一个地址
}
int main()
{
	char arr1[20] = "hello world!";
	char arr2[] =   "************";
    my_strcpy(arr2, arr1);
	printf("%s\n", arr2);
	return 0;
}

程序的运行结果为: hello world!

这个字符串拷贝函数是我自己定义的一个函数,叫做my_strcpy函数。

my_strcpy函数的返回值类型是char*,即返回一个地址,有两个参数,一个
是目标拷贝字符串的地址,一个是不能被改变的源字符串的内容的地址。

Debug版本中assert断言的作用是告诉程序员错误出现在哪里,而在release版本,assert又会被优化掉。

在while循环中,源字符串的内容拷贝到目标字符串之后,指针指向下一个字符的地址,继续进行拷贝过程,当指针指向’\0’时,源字符串中的’\0’拷贝到目标字符串,这时*dest==0,循环结束,’\0’也被拷到目标字符串里。

这样,hello world!就被完全拷贝到了arr2里,在主函数里调用这个函数,最终程序结果就是上述结果。

while(*scr++==*dest++)

如果代码如上所示,在第二个参数前加上const,这一条语句就无法正确编译。

字符串函数模拟实现:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<assert.h>
#include<string.h>
int my_strlen(char*str)//返回值为整型,也可以是size_t,表示无符号的整型
{
	int count = 0;
	assert(str != NULL);//断言
	while (*str++ != '\0')
	{
		count++;
	}
	return count;
}
int main()
{
	int len = my_strlen("abcd");
	printf("%d\n", len);
	return 0;
}

程序的执行结果为:4。

同样,我自己定义了my_strlen的函数,来模拟实现库函数里的strlen函数。
my_strlen函数返回一个整型,参数传的是一个字符串str不能被改变的的地址。

定义一个计时器count,断言字符指针str不为空指针,while循环中*str !==’\0’代表字符串中的字符不为\0,计数器加一,然后指针向后移动一位,指向下一个字符,

直到字符串中的字符等于\0,循环结束,返回计数器个数。
在主函数中,调用my_strlen函数,将这个值放在定义的len变量中,最终的程序结果也为上述结果。

字符串追加函数的模拟实现

char* my_strcat(char* dest, const char* src)
{
	char* ret = dest;
	assert(dest != NULL);
	assert(src != NULL);
	//1. 找目标空间的'\0'
	while(*dest)
	{
		dest++;
	}
	//2. 追加
	while(*dest++ = *src++)
	{
		;
	}
	return ret;
}
int main()
{
	char arr1[20] = "hello ";
	my_strcat(arr1, arr1);
	printf("%s\n", arr1);
	return 0;
}

以此类推,定义my_strcat函数,它的返回值、参数和my_strcpy函数一样。

断言的作用也是相同的,第一个while循环判断*dest是否为’\0’,当循环到’*dest ==\0’时,循环停止,执行下一个while循环,它的作用和my_strcpy函数的作用一样,在上一个’\0’后面开始拷贝字符串。

字符串追加函数要注意5点:

1.目标字符串中必须有’\0’

2.源字符串中必须有’\0’

3.目标字符串必须可修改

4.目标空间必须足够大

5.自己不能给自己追加

字符串比较函数的模拟实现

int my_strcmp(const char* str1, const char* str2)
{
	assert(str1 != NULL);
	assert(str2 != NULL);

	while(*str1 == *str2)
	{
		if(*str1 == '\0')
			return 0;
		str1++;
		str2++;
	}

	return *str1-*str2;
}

int main()
{
	char* str1 = "abc";
	char* str2 = "abcdef";

	int ret = my_strcmp(str1, str2);
	printf("%d\n", ret);
	return 0;
}

定义my_strcmp函数,参数都是不能改变的字符串的地址,返回值是大于0,小于0或者等于0的值。

先断言指针是否指向空的地址,再进入while循环中,判断两个字符串中的字符从左往右是否相等,如果两个字符串内的字符都是’\0’,则直接返回0。

return str1-str2的含义为,当str1大于str2时,返回一个正数;当str1小于str2时,返回一个负数;当*str1等于 *str2时,返回0。

在字符串查找字符串函数的模拟实现

char* my_strstr(const char* str1, const char* str2)
{
	const char* s1 = str1;
	const char* s2 = str2;
	const char* pstart = str1;
	assert(str1 != NULL);
	assert(str2 != NULL);
	//查找
	if(*str2 == '\0')
		return (char*)str1;

	while(*pstart)
	{
		s2 = str2;
		s1 = pstart;
		while(*s1 && *s2 && *s1==*s2)
		{
			s1++;
			s2++;
		}
		if(*s2 == '\0')
		{
			return (char*)pstart;
		}
		pstart++;
	}
	return NULL;
}

int main()
{
	char arr1[] = "abbbcdef";
	char arr2[] = "bbc";
	char* ret = my_strstr(arr1, arr2);
	if(ret == NULL)
	{
		printf("不存在\n");
	}
	else
	{
		printf("%s\n", ret);
	}
	return 0;
}

定义my_strstr函数,返回值为char*,参数为字符串不可变的两个字符串的地址.

在逻辑分析前,定义三个char*类型的指针,分别为s1,s2,pstart.将str1的首地址赋给 s1 和start,把str2的地址赋给s2.

进行断言,判断指针变量str1和str2是否为空指针,判断如果str2是一个空字符串, 直接返回str1.当*start不为’\0’时进入第一个循环,str2的首地址给s2,start的首地址给s1.

进入第二个循环,当s1,s2不等于’\0’且s2等于s1时,指针s1,s2向右移动一位. 当循环跳出来时,*s2如果等于’\0’,则说明字符串str2已经被找完,返回指针变量pstart.

如果s2不等于s1时,且*s2 != '\0’时,循环跳出,这时start向后移动一位,将指针pstart指向的地址给s1.

将指针str2指向的地址重新给s2,这样指针s2又重新指向str2字符串的第一个字符,重新开始查找.如果*pstart==’\0’,则返回NULL.

在主函数中,定义一个指针变量ret,将函数的地址赋给ret,则如果ret==NULL,说明不存在,否则,,如上面的代码返回字符串bbcdef。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值