赶紧来修炼内功~字符串函数详解大全(一)

目录

1.strlen

重点:

模拟实现:

法一:

法二:

法三:

2.strcpy

重点:

模拟实现:

3.strcat

重点:

模拟实现:

4.strcmp

重点:

模拟实现


1.strlen

strlen函数是用来计算字符串长度的

重点:

  1. 字符串以  '\0' 作为结束标志 strlen 函数返回的是在字符串中 '\0' 前面出现的字符个数(不包含 '\0' )
  2. 注意函数的返回值为 size_t ,是无符号的( 易错
  3. 参数指向的字符串必须要 '\0' 结束

1. 

 

这里答案为6,确实是有6个字符,但是没有看到'\0'啊!

其实,'\0'是在最后一个字符后面自动添加的

 我们进一步验证该字符函数是以'\0'来计算字符串长度的我们可以在字符串的中间部分手动添加一个'\0'。

这时,字符串就提前终止,计算到的数值为3。

 2.

前面字符串的长度为3,后面字符串的长度为4,按理说应该是打印小于号,但是这里却是大于号!

其实,无论你怎么减,这里都只能是大于号,因为strlen函数的定义类型就是size_t类型,即无符号整形,所以无论如何他都是大于0的。

3.

 

如上图代码,字符串中只有4个字符,但是却输出有74个字符,那是因为,这种定义的字符串后面不会自动添加'\0',strlen函数要一直向后读取,直到找到'\0'为止,这个数值是随机的。 

 因此,strlen函数的参数指向的字符串必须要'\0' 结束

模拟实现:

创建一个my_strlen函数,模拟实现strlen函数的功能:

法一:

计数器的方式,只要遇到'\0'就停止

size_t my_strlen(const char* str)//返回值类型和参数与原函数保持一致
{
	int num = 0;
	while (*str != '\0')//当不等于'\0'时进入循环
	{
		num++;//计数器加一
		str++;//向后移动一位
	}
	return num;//最后循环结束,返回计数器的值,即为字符串的长度
}
int main()
{
	char arr[] = "abcdef";
	int ret = my_strlen(arr);
	printf("%d\n", ret);
	return 0;
}

 法二:

不能创建临时变量计数器,使用递归算法:

size_t my_strlen(const char* str)//返回值类型和参数与原函数保持一致
{
	if (*str == '\0')//若该字符为'\0'就返回0.
		return 0;
	else
		return 1 + my_strlen(str + 1);//不是'\0'就返回1+my_strlen(str+1),实现递归
}
int main()
{
	char arr[] = "abcdef";
	int ret = my_strlen(arr);
	printf("%d\n", ret);
	return 0;
}

法三:

 指针-指针的方式:(我们之前讲过指针-指针得到的时两个指针间的元素个数)

size_t my_strlen(const char* str)//返回值类型和参数与原函数保持一致
{
	char* p = str;//创建一个char* 类型保存字符串的起始位置
	while (*str != '\0')//当*str不为'\0'时,str++一下指向下一个字符,否则结束循环,
		str++;          //否则结束循环,得到字符串的结束位置
	return str - p;//最终两个指针相减,得到中间的元素个数
}
int main()
{
	char arr[] = "abcdef";
	int ret = my_strlen(arr);
	printf("%d\n", ret);
	return 0;
}

2.strcpy

 strcpy函数是将source指向的字符串拷贝到destination指向的空间中,同时覆盖该空间中原有的字符串

重点:

  1. 源字符串必须 '\0' 结束
  2. 会将源字符串中的 '\0' 拷贝到目标空间
  3. 目标空间必须足够大,以确保能存放源字符串。
  4. 目标空间必须可变

 1.

与上一个strlen函数相似,这里需要'\0'来判断拷贝是否完成,当source指向的字符串读取到'\0'时拷贝就结束了。

2.

int main()
{
	char arr1[] = "abcdefghij";
	char arr2[] = "qwerhhhh";
	strcpy(arr1, arr2);
	printf("%s\n", arr1);
	return 0;
}

 通过监视,我们发现arr1字符串中有两个'\0',其中红色的'\0'是由arr2字符串拷贝过来的黑色的'\0'是arr1字符串中自带的

3.

这条就不用过多解释了吧,目标空间不够大的话根本拷贝不过去的,编译器也会报错。

4.

目标空间的内容必须可变,不能是常量字符串。

发生访问冲突,就是p指向的这个常量字符串不可以被修改,就不能使用strcpy函数。

模拟实现:

创建一个my_strcpy函数,模拟实现strcpy函数的功能: 

#include <assert.h>//assert函数所需的头文件
char* my_strcpy(char* dest, const char* src)//返回值类型和参数类型与原函数保持一致,
{//dest所指向的字符串需要被修改,不用const保护,src所指向的字符串不需要被修改用const修饰保护
	assert(dest && src);//断言一下,保证两个指针均不为空指针,若为空指针则中止程序并报错
	char* ret = dest;//创建一个char*变量保存起始地址,后面需要返回起始地址
	while (*dest++ = *src++)//将src所指向的内容赋值给dest所指向的内容,
		;                   //也可以赋值'\0'然后就被判定为假,退出循环
	return ret;//返回起始地址,容易形成链式访问
}
int main()
{
	char arr1[] = "xxxxxxxxxxx";
	char arr2[] = "abcdef";
	printf("%s\n", my_strcpy(arr1, arr2));
	return 0;
}

3.strcat

 在destination指向的字符串后面追加一个source指向的字符串

int main()
{
	char arr1[15] = "hello ";
	char arr2[] = "world!";
	strcat(arr1, arr2);

	return 0;
}

重点:

  1. 源字符串必须 '\0' 结束
  2. 目标空间必须有足够的大,能容纳下源字符串的内容。
  3. 目标空间必须可修改
  4. 会将源字符串中的 '\0' 拷贝到目标空间

1、2、3.

 与上面所诉的strcpy函数相似,这里就不多赘述了。

4.

int main()
{
	char arr1[15] = "hello \0xxxxxxx";
	char arr2[] = "world!";
	strcat(arr1, arr2);

	return 0;
}

  通过监视,我们发现arr1字符串中有两个'\0',其中红色的'\0'是由arr2字符串追加过来的黑色的'\0'是arr1字符串中自带的

模拟实现:

 创建一个my_strcat函数,模拟实现strcat函数的功能:

#include <assert.h>
char* my_strcat(char* dest, const char* src)
{
	assert(dest && src);
	char* ret = dest;         //上面的代码与前几个模拟实现的函数原因相同,这里就不多赘述了
	while (*dest != '\0')  //找到dest指针指向的字符串的末尾的'\0'
		dest++;
	while (*dest++ = *src++)//将src所指向的内容赋值给dest所指向的内容, 
		;                   //也可以赋值'\0'然后就被判定为假,退出循环
	return ret;//最后返回字符串的起始地址
}
int main()
{
	char arr1[15] = "abcdef";
	char arr2[] = "1234";
	printf("%s\n", my_strcat(arr1, arr2));
	return 0;
}

4.strcmp

strcmp是用来比较两个字符串大小的 

重点:

strcmp比较的是对应位置上字符的大小,而非字符串的长度

模拟实现:

创建一个my_strcmp函数,模拟实现strcmp函数的功能:

#include <assert.h>
int my_strcmp(const char* str1, const char* str2)//返回值类型和参数类型与原函数保持一致
{                 //该函数只是比较两个字符串的大小,不对字符串进行修改,所以用const保护起来
	assert(str1 && str2);    //断言,防止参数为NULL
	while (*str1 == *str2)   //比较字符,当两字符不同时就跳出来
	{
		if (*str1 == '\0')
			return 0;       //判断是否已经比较到了末尾,若为'\0'则表示两字符串相等
		str1++;
		str2++;
	}
	return *str1 - *str2;   //返回直接就用两字符相减
}
int main()
{
	char arr1[] = "abcdef";
	char arr2[] = "abcefg";
	printf("%d\n", my_strcmp(arr1, arr2));
	return 0;
}
  • 13
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 11
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

蒲公英的吴

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

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

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

打赏作者

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

抵扣说明:

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

余额充值