字符串函数的模拟实现

今天我们来了解以下一些字符串函数的模拟实现:
strlen strcpy strcat strcmp

strlen函数的模拟实现

首先我们转到cplusplus中查找strlen的官方解释:
通过查找我们了解到,strlen是用来测量一个字符串长度的函数,函数的返回值就是字符的长度
字符串以 ‘\0’ 作为结束标志,strlen函数返回的是在字符串中 ‘\0’ 前⾯出现的字符个数(不包含 ‘\0’ )。

函数原型如下

size_t strlen ( const char * str )

字符串函数的模拟实现_第1张图片
下面我们来简单了解以下strlen函数的使用(strlen函数等字符串函数的头文件一般都是string.h)
例如:我们测量一下字符串“abcdef”的字符串长度

int main()
{
	char arr[] = "abcdef";
	int len = strlen(arr);
	printf("此字符串的长度是%d\n", len);
	return 0;
}

运行结果如下:
字符串函数的模拟实现_第2张图片
下面我们就可以开始strlen函数的模拟实现了:
我们在之前已经知道,strlen就是从字符串的第一个元素开始往后找"\0",知道找到"\0",一旦找到,函数就立即停止,返回元素个数,这样理解,我们就可以更好地开始它的模拟实现了

方法一:以计数的方式实现

我们定义一个count,用while循环实现count的++,str为字符串的第一个元素的地址,也就是我们常说的首地址,如果解引用后(str)不是"\0",的话,count就++,也就是说元素个数+1,count++后str的位置也要往后移动,所以str++,当str=="\0"时循环停止,count就是字符串的长度了
字符串函数的模拟实现_第3张图片

代码如下:

int my_strlen(const char * str)
{
 int count = 0;
 assert(str);//进行断言操作,防止str为空
 while(*str)
 {
 count++;
 str++;
 }
 return count;
}
方法二:以递归的方式实现(不能创建临时变量时)

有时候一些题目可能会要求咱们不能创建临时变量来模拟实现,这个时候我们就可以想到递归:
思路如下:
字符串函数的模拟实现_第4张图片

int my_strlen(const char * str)
{
 assert(str);
 if(*str == '\0')
 return 0;
 else
 return 1+my_strlen(str+1);
}
方法三:以指针的方式实现

在之前的指针学习中我们可以知道指针-指针=两个之间的元素个数,所以这里我们首先定义一个指针变量p为str(字符串首地址),然后用while循环将p移动到\0之前的位置,然后相减得出的值就是字符串str的长度了
代码如下:

int my_strlen(char *str)
{
 assert(str);
 char *p = str;
 while(*p != ‘\0’ )
 p++;
 return p-str;
}
strcpy函数的模拟实现

老规矩,cplusplus查一下:
字符串函数的模拟实现_第5张图片
函数原型如下:

char* strcpy(char * destination, const char * source );

这里我们要注意:
• 源字符串必须以 ‘\0’ 结束
• 会将源字符串中的 ‘\0’ 拷⻉到⽬标空间
• ⽬标空间必须⾜够⼤,以确保能存放源字符串
• ⽬标空间必须可变
例如,我们将abcde拷贝到des中去:
我们可以打开调试窗口调试一下,就可以看到des将src中的\0也拷贝过去了
字符串函数的模拟实现_第6张图片
下面我们开始strcpy函数的模拟实现,用指针可以轻松的解决问题:
这里我们要记得断言!如果不断言就是报警,因为*解引用了NULL
当 *src不等于\0时,while循环就继续进行,将src解引用的值赋给 dest,同时dest和src的指针一起往右移动,当src等于\0时,循环跳出,拷贝完成
这里我们要将dest的首地址记录下来,因为官方的函数定义是要求这个函数返回dest的首地址的

char* my_strcpy(char* dest, const char* src)
{
	char* ret = dest;
	assert(dest != NULL);
	assert(src != NULL);

	while (*src)
	{
		*dest=*src;
		dest++;
		src++;
	}
	return ret;
}

也可以简化:

char *my_strcpy(char *dest, const char*src)
{ 
 char *ret = dest;
 assert(dest != NULL);
 assert(src != NULL);
 
 while((*dest++ = *src++))
 {
 ;
 }
 return ret;
}
strcat函数的模拟实现

strcat的作用时将src链接到dest后面,并且这里也要返回dest的首地址
字符串函数的模拟实现_第7张图片
这里需要注意几点:
• 源字符串必须以 ‘\0’ 结束。
• ⽬标字符串中也得有 \0 ,否则没办法知道追加从哪⾥开始。
• ⽬标空间必须有⾜够的⼤,能容纳下源字符串的内容。
• ⽬标空间必须可修改。
我们调试看一看:
我们发现,src的内容就是从dest的\0的位置开始追加的
字符串函数的模拟实现_第8张图片
下面我们就可以开始模拟实现了
同样的我们需要用ret保存dest的首地址,同时记得断言
我们首先将dest的位置右移到\0的位置,然后再将src解引用的值赋给 dest,同时dest和src的指针一起往右移动,当src等于\0时,循环结束,追加完成

char *my_strcat(char *dest, const char*src)
{
 char *ret = dest;
 assert(dest != NULL);
 assert(src != NULL);
 while(*dest)
 {
 dest++;
 }
 while((*dest++ = *src++))
 {
 ;
 }
 return ret;
}
strcmp函数的模拟实现

strcmp时用于比较两个字符串的,此函数开始比较每个字符串的第一个字符。如果它们彼此相等,则继续以下对,直到字符不同或达到终止 null 字符为止,如果str1大于str2(⽐较两个字符串中对应位置上字符ASCII码值的⼤⼩),返回 一个大于0的值,str1小于str2,返回 一个小于0的值,如果完全等于,就返回0
字符串函数的模拟实现_第9张图片
例如:
abcde和abcee比较,由于d的acs码值要小于e所以会返回一个小于0的值
字符串函数的模拟实现_第10张图片
我们直接用while循环,如果相等,就继续往下走,不相等就就直接放回他们的差值,也就是asc码值相减,如果相等就为0,大于就时大于0,小于就小于0
代码如下:

int my_strcmp (const char * str1, const char * str2)
{
 int ret = 0 ;
 assert(src != NULL);
 assert(dest != NULL);
 while(*str1 == *str2)
 {
 if(*str1 == '\0')//此时两个字符串都遍历完成,且相等,直接返回0
 return 0;
 str1++;
 str2++;
 }
 return *str1-*str2;
}

好了,今天的分享到这里就结束了,谢谢大家!

你可能感兴趣的:(算法,开发语言,c语言)