【C语言入门】库函数模拟实现(1)

 

✨✨欢迎大家来到Celia的博客✨✨

🎉🎉创作不易,请点赞关注,多多支持哦🎉🎉

所属专栏:C语言

个人主页Celia's blog~

 

目录

引言

一、strcmp与strncmp

1.1 strcmp

1.1.1 作用

1.1.2 模拟实现思路

1.1.3 代码实现

 1.2 strncmp

1.2.1 作用

1.2.2 模拟实现思路

1.2.3 代码实现

二、strcat与strncat

2.1 strcat

2.1.1 作用

2.1.2 模拟实现思路 

2.1.3 代码实现

2.2 strncat

2.2.1 作用 

2.2.2 模拟实现思路

2.2.3 代码实现

三、strcpy与strncpy

3.1 strcpy

 3.1.1 作用

3.1.2 模拟实现思路

3.1.3 代码实现

 3.2 strncpy

 3.2.1 作用

3.2.2 模拟实现思路

3.2.3 代码实现

四、strstr

4.1 作用

4.2 模拟实现思路

4.3代码实现


引言

  在头文件<string.h>中,包含了许多字符串函数,本篇文章将详细介绍以及实现常用的字符串函数。

一、strcmp与strncmp

1.1 strcmp

int strcmp ( const char * str1, const char * str2 );

1.1.1 作用

  拥有两个指针参数,分别指向两个字符串的首地址,用于比较两个字符串的大小,若str1>str2,返回值>0,若str1<str2,返回值<0,若两个字符串相等,则返回0。

比较规则:依次比较相同位置下的字符的ASC码值,与字符串长度没有直接联系。

1.1.2 模拟实现思路

  我们需要从字符串的首元素开始依次向后比较,这个环节可以用一个循环来实现,如果循环过程中,两个元素相等且这两个元素都是'\0',则说明这两个字符串相等。反之,如果有其中一对字符不相等,则会跳出循环,返回两个字符的差值(ASC码的差值)即可。

1.1.3 代码实现

int my_strcmp(const char* str1, const char* str2)
{
	while (*str1 == *str2)
	{
		str1++;
		str2++;
		if (*str1 == '\0')//在循环内,这两个指针指向的元素是相等的
			return 0;
	}
	return *str1 - *str2;
}

 1.2 strncmp

int strncmp ( const char * str1, const char * str2, size_t num );

1.2.1 作用

  strncmp与strcmp相比多了一个无符号整型参数 ,用来传输需要进行比较的字符数量,也就是说,我们可以控制比较前 num 个字符。

1.2.2 模拟实现思路

  大体思路不变,只需要让循环的次数受到限制即可。

1.2.3 代码实现

int my_strncmp(const char* str1, const char* str2,size_t num)
{
	while (*str1 == *str2)
	{
		num--;
		str1++;
		str2++;
		if (num == 0)
			return 0;
	}
	return *str1 - *str2;
}

二、strcat与strncat

2.1 strcat

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

2.1.1 作用

  拥有两个指针参数,分别指向两个字符串的首地址,用于把source指向的字符串拼接到destination指向的字符串后,并返回destination所指向的字符串的首地址。

2.1.2 模拟实现思路 

   既然是拼接字符串,那么首先就要找到目标字符串的结束符('\0'),并记录位置,再进行拷贝。

2.1.3 代码实现

char* my_strcat(char* destination, const char* source)
{
	assert(destination && source);//断言,避免空指针
	char* p = destination;//记录首地址
	while (*++destination != '\0');//找到目标字符串的结束符位置,注意前置自增,否则会跳过\0
	while (*destination++ = *source++);//赋值
	return p;//返回首地址
}

2.2 strncat

char * strncat ( char * destination, const char * source, size_t num );

2.2.1 作用 

  与strcat相比多了一个无符号整型参数,用于实现固定字符数量的拼接。

2.2.2 模拟实现思路

  与strcat一样,首先要找到目标字符串的结束符,然后进行固定次数的赋值操作,最后在字符串的结尾补充一个\0。

2.2.3 代码实现

char* my_strncat(char* str1, const char* str2, size_t num)
{
	assert(str1 && str2);
	char* p = str1;
	while (*++str1);//找到结束符
	while (num--)//固定次数的赋值操作
	{
		*str1++ = *str2++;
	}
	(*str1) = '\0';//补充结束符
	return p;
}

三、strcpy与strncpy

3.1 strcpy

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

 3.1.1 作用

  拥有两个指针参数,分别指向两个字符串的首地址,用于把source所指向的字符串拷贝至destination所指向的字符串,并且返回destination所指向的字符串的首地址。

3.1.2 模拟实现思路

  我们只需要用一个循环遍历整个source字符串,将source中的每一个元素拷贝至destination字符串。

3.1.3 代码实现

char* my_strcpy(char* str1, const char* str2)
{
	assert(str1 && str2);//断言
	char* p = str1;
	while (*str1++ = *str2++);//赋值
	return p;
}

 3.2 strncpy

char * strncpy ( char * destination, const char * source, size_t num );

 3.2.1 作用

  与strcpy相比多了一个无符号整型参数,用于拷贝固定数量的字符。

3.2.2 模拟实现思路

  我们需要在循环内控制赋值的次数,拷贝的方式与strcpy相同。

3.2.3 代码实现

char* my_strncpy(char* str1, const char* str2, size_t num)
{
	assert(str1 && str2);
	char* p = str1;
	while (num--)//控制次数
	{
		*str1++ = *str2++;
	}
	return p;
}

注意:目标字符串在拷贝完成后不需要添加结束符

四、strstr

 char * strstr ( const char * str1, const char * str2 );

4.1 作用

 拥有两个指针参数,分别指向两个字符串的首地址,用于查找目标字符串中的子字符串,并且返回这个子字符串在目标字符串中第一次出现的首地址。

4.2 模拟实现思路

  • 我们需要一个额外的指针 cur 来记录每一次查找的首地址,以便于最后返回地址。
  • 我们需要两个额外的指针变量p1,p2,分别用于比对目标字符串和被查找的字符串中的元素。
  • 当查找失败时,当前的 cur 位置将不再适用,需要向后移动一位,指向被查找的字符串的指针应重新回到初始位置。
  • 如果p1和p2所指向的元素相同,则继续向后比较,这里可以用while循环来实现。
  • 当指向被查找的字符串的指针遇到\0时,说明查找成功,返回cur。
  • 如果cur移动到目标字符串的\0位置,说明查找失败,目标字符串中没有被查找的子字符串,返回空指针(NULL)。

4.3代码实现

 

char* my_strstr(const char* str1, const char* str2)
{
	const char* s1 = NULL;//只用于比对,不希望更改目标,可以用const修饰
	const char* s2 = NULL;
	const char* cur = str1;//第一次开始比对的位置为目标字符串的首元素
	if (*str2 == '\0')//当被查找的字符串为空时,直接返回目标字符串即可(判断隐藏的\0)
	{
		return (char*)str1;
	}
	while (*cur)//当cur移动到目标字符串的末尾,查找失败,会跳出循环(\0的值为0)
	{
		s1 = cur;//记录目标字符串
		s2 = str2;//记录被查找的字符串
		while (* s1 != '\0' && * s2 != '\0' &&  * s1 == * s2)//相等且不为\0时
		{
			s1++;//继续进行比对,直到一方遇到\0跳出循环
			s2++;
		}
		if (*s2 == '\0')//如果指向被查找的字符串的指针指向的元素为\0,说明查找成功,返回cur
		{
			return (char*)cur;//强制类型转换
		}
		cur++;//当指向两个字符串的指针指向的元素不同时,当前cur位置不再适用,自加
	}
	return NULL;//查找失败返回空指针
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Celia~

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

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

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

打赏作者

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

抵扣说明:

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

余额充值