如果我们简单按照库函数思路来,不考虑题目前半部分的要求,会先想到strlen函数去计算字符串的长度,实现代码如下:
#include<stdio.h>
#include<string.h>
int main()
{
char arr[] = "abc";
int n = strlen(arr);
printf("n = %d\n",n);
return 0;
}
输出结果为:
但是如果加上题目的要求,其实思路就变成了我们自己去创建一个函数去代替strlen,同时还能有和strlen一样的实现效果,假设这个函数我们设为new_strlen,则实现代码如下:
#include<stdio.h>
int new_strlen(char* str)//返回值为字符串的长度,利用指针去实现传址调用
{
int num = 0;
while(*str != '\0')
{
num++;
str++;
}
return num;
}
int main()
{
char arr[] = "abc";
int n = new_strlen(arr);
printf("n = %d\n",n);
}
要注意的有以下几点:
1,arr属于数组,数组在传参的时候,传过去的并不是整个数组,而是第一个元素的地址,所以我们的str便是第一个元素'a'的地址。
2,在获得第一个元素的地址之后,我们进入while循环,判断第一个元素是否为‘\0',因为它是字符串结束的标志,但并不计入数组的内容,所以我们判断不相等的时候,进入循环,地址往后进一个,相当于指针地址现在指着第二个元素,判断是否为‘\0‘,同时计数+1,这样当我们遇到'\0'的时候,循环停止,输出的即是字符串的长度值num。这样我们也可以更加深刻感受到strlen库函数的实现过程。
当我们完整地去完成题目要求的时候,它说不允许创建临时变量,也就是没有了上述用于计数的num值,我们就要着手于递归的思想,主要思考方向是这样的:因为没有计数的临时变量供我们以利用,所以我们可以通过当一个str在未检测到‘\0'的时候,会通过连续加一来实现之前new_strlen函数的实现结果,也就是,1+new_strlen的一个递归,具体来看代码比较好理解一些:
#include<stdio.h>
int new_strlen(char* str)//返回值为字符串的长度,利用指针去实现传址调用
{
if(*str != '\0')
{
return 1+new_strlen(str+1);//递归实现一个一个去检测是否等于'\0',‘归“的时候因为最后进到了return0,return0返回给上面的1+new_strlen中的new_strlen,如此循环递归;
}
else
return 0;//如果第一下就没找到直接归零;
}
int main()
{
char arr[] = "abc";
int n = new_strlen(arr);
printf("n = %d\n",n);
}
这样也就能像上述代码一样实现输出效果!
有几点要注意:
1,应是“str+1"而非“str++",因为str++是先去使用str的值再加加,这样就会出现错误(栈溢出,死循环);
2,在“归”的时候,因为我们最后检测到了‘\0‘,所以返回值为0,而它返回的位置就是上一个“return 1+new_strlen(str+1)"的new_strlen(str+1)中,即现在是1+0=1;然后依次往上返回值,最终输出结果为0+1+1+1=3。
3,该题与上一题做比较的话,会发现,上一题当我们归的时候返回到print那里,上题没有else于是我们直接顺延下去,继续执行printf的工作。而该题我们返回到new_strlen这里,因为此时这句话还没有执行完,即return 1+new_strlen(str+1)只执行了new_strlen(str+1)的部分,所以我们要回来继续执行未完成的部分,上题那句话是已经执行过了的所以直接顺延就行。
题目来源:B站比特鹏哥,和上一题相照应,这只是我自己的一些理解罢,仅供参考!