![](https://i-blog.csdnimg.cn/blog_migrate/61dff0b02856d5847bf825cb23fb9821.png)
以上是c++网站对此库函数的说明
可以看到函数的参数是一个字符指针,返回类型是一个无符号整形size_t
1.strlen函数的参数以及返回值
参数本质上是通过传入的地址对字符串个数进行统计
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
int main()
{
char* p;
char arr[] = "love";
p = arr + 1;
printf("%d %d", strlen(p), strlen(arr));
}
![](https://i-blog.csdnimg.cn/blog_migrate/90f32a19d2e6621d38c3eb3c6946fe80.png)
常见错误案例
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
int main()
{
char* p;
char arr[4] = {'l','o','v','e'};
p = arr + 1;
printf("%d %d", strlen(p), strlen(arr));
}
![](https://i-blog.csdnimg.cn/blog_migrate/0a32bbe5459eb87ce064a683bd91e14c.png)
产生这种情况是因为未初始化的内存中存储的是随机值
而strlen只是不计算 \0之后的数据,因此在用strlen统计字符串字符个数一定要包含结束标志\0,以免越界访问产生一些意想不到的bug
事实上,printf输出也一样printf是以%s,字符串的形式输出,遇到字符 ‘\0’ 就认为到达 数组末端了,然后就停止输出了。
下面思考下面代码
int main()
{
const char* str1 = "abcrrt";
const char* str2 = "bbb";
if (strlen(str2) - strlen(str1) > 0)
{
printf("str2>str1\n");
}
else
{
printf("srt1>str2\n");
}
return 0;
}
![](https://i-blog.csdnimg.cn/blog_migrate/7035ecbb40a5755b9a3a6cfbb292b7b7.png)
其实它的结果是完全无法预测的
2.VS中库函数的实现
size_t __cdecl strlen (
const char * str
)
{
const char *eos = str;
while( *eos++ ) ;
return( eos - str - 1 );
}
![](https://i-blog.csdnimg.cn/blog_migrate/d17b534f7e6e4a61b97e6540a020cd72.png)
3.几种模拟实现strlen函数
3.1遍历法
int my_strlen(const char* str)
{
int i = 0;
if (*str !='\0' )
{
i++;
str++;
}
return 0;
}
3.2递归法
int my_strlen2(const char* str)
{
if (*str != '\0')
{
return my_strlen(++str) + 1;
}
}
3.3指针相减等于中间所含元素个数
int my_strlen2(const char* str)
{
const char* tmp;
tmp = str;
while (tmp++);
return (str - tmp - 1);
}
VS库函数选择的显然是第三种方式。
4.strlen和sizeof
初学者时常会将两者弄混,但其实两者有着有着本质的区别,sizeof是操作符,计算的变量所占的空间大小是多少个字节。strlen是c语言所提供的的库函数,用来统计从传入的地址统计字符串个数,直到遇到\0。