目录
代码逻辑
- 创建一个字符串数组,并接收一个字符串
- 创建一个函数,求出字符串的长度,只有将数组名传递给形参
- 定义my_strlen函数,实参是数组名,而数组名是首元素的地址,所以形参以char*类型的指针接收
- my_strlen函数返回的是字符串的元素个数大小,所以返回值为int类型
- 创建int类型的变量用来接收my_strlen函数的返回值,并打印验证
int my_strlen(char* str)
{
}
int main()
{
//创建字符串数组
char arr[] = "abc";
//创建函数
int len = my_strlen(arr);
//验证
printf("%d\n", len);
return 0;
}
my_strlen函数的具体实现
- 如:my_strlen函数要求长度的字符串是"abc"
- "abc"字符串的末尾隐藏了一个'\0'(字符串结束标志),所以"abc"字符串的全部内容为['a', 'b', 'c', '\0']
- my_strlen("abc") - 此时的str指针变量指向的是a字符的地址,那么就将str+1指向下一个字符的地址,并且字符'a'为有效长度,所以要在此基础上加1
- 1 + my_strlen("bc") - 此时str指向的是b字符的地址,同样将str+1指向下一个字符,且'b'为有效长度,所以再加1
- 1 + 1 + my_strlen("c") - 同上,str+1指向下一个字符,且'c'字符为有效长度,同样再加1
- 1 + 1 + 1 + my_strlen("\0") - 此时的str指向的是'\0',遇到了字符串结束标志,那么str就不再往后走,并且在此基础上加0
- 1 + 1 + 1 + 0 = 3 - 这样就计算出了字符串的长度,并且没有创建临时变量
- 以上的代码逻辑可使用递归实现,也就是函数自己调用自己
#include<stdio.h>
int my_strlen(char* str)
{
if (*str == '\0')
{
return 0;
}
else
{
return 1 + my_strlen(str + 1);
}
}
int main()
{
//创建字符串数组
char arr[] = "abc";
//创建函数
int len = my_strlen(arr);
//验证
printf("%d\n", len);
return 0;
}
解析my_strlen函数体的代码
同样拿"abc"字符串举例
- 进入时:
- 第一次:if语句判断str解引用是否为0,此时的st解引用是字符'a',所以条件为假,从而执行else语句,虽然return是返回,但是返回的语句中包含了my_strlen函数,所以要再次进入my_strlen函数(函数自己调用自己,这样就是递归)
- 第二次:第一次my_strlen函数传递的是str+1,也就是将字符'b'的地址传递给了char* str接收,此时的str指向的就是字符'b',同样if条件不成立,执行else语句,再次重新进入my_strlen函数
- 第三次:第二次my_strlen函数传递的是字符'c'的地址,所以此时的str指向的是字符'c',if条件不成立,执行else语句,再次进入my_strlen函数
- 第四次:第三次my_strlen函数传递的是'\0',此时的str指向了'\0',满足了if条件,直接返回0
- 返回时:
- 回到第三次:此时的my_strlen函数返回值为0,所以是1+0 = 1
- 回到第二次:此时的my_strlen函数返回值为1,所以是1+1 = 2
- 回到第一次:此时的my_strlen函数返回值为2,所以是1+2 = 3
此时就将所有my_strlen函数的递归完成,并且将3返回