一.问题导入
题目:请编写函数不允许创建临时变量,求字符串长度
我们先来回忆一下,之前我们是如何求字符串长度的,我们来看以下代码:
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
int main(void){
char arr[] = "hello";
int len = strlen(arr);
printf("len=%d",len);
getchar();
return 0;
}
arr数组中存着 hello 这个字符串,我们只需要使用strlen()函数对数组进行计算,然后将结果赋值给变量len,最后输出len的值就可以得到这个字符串的长度,如图所示:
那我们可以自己写一个函数名为my_strlen(),我们需要计算某个字符串长度的时候只需要将数组/字符串传入该函数即可,但是我们之前就说过,arr是一个数组,数组传参,传过去的不是一整个数组而是第一个元素的地址,既然传过去的是一个地址,那么我们自定义函数的形参类型就是char*,因为我们求的是字符串的长度,那么函数需要返回的类型就应该是一个整型(int类型),所以我们可以这样写:
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
int my_strlen(char *str){
//功能实现
}
int main(void){
char arr[] = "hello";
int len = my_strlen(arr);
printf("len=%d",len);
getchar();
return 0;
}
接下来我们就要着重将函数的功能实现部分了,我们既然知道了传入的是首元素的地址,那么我们可不可以写一个while()循环语句,当 *str 不等于 '\0' 的时候则代表还没有读取完成,一旦 *str 的值等于0的时候则代表已经字符串已经被读取完成,再创建一个变量count来计算读取的次数,依据上面的思想,我们可以编写如下代码:
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
int my_strlen(char *str){
int count = 0;
while(*str != 0){
count++;
*str++;
}
return count;
}
int main(void){
char arr[] = "hello";
int len = my_strlen(arr);
printf("len=%d",len);
getchar();
return 0;
}
程序运行截图如下所示:
我们可以看到程序正确的输出字符串的长度,证明我们上面的代码是行得通的
但是题目的要求是不允许创建临时变量,这里的count变量用来统计字符串的长度,但是当函数调用完成后count的值便会自动销毁,这就是临时变量,那我们该怎么办呢?
这时候我们来看一下这段代码:
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
int my_strlen(char *str){
if (*str != '\0'){
return 1 + my_strlen(str+1);
}
else{
return 0;
}
}
int main(void){
char arr[] = "hello";
int len = my_strlen(arr);
printf("len=%d", len);
getchar();
return 0;
}
这段代码用到了函数的递归,首先使用if语句,如果 *str 不等于 '\0' 则返回1+my_strlen(str+1)
可能这里有点懵,我们来看一下图就明白了:
我们将字符串进行拆解,将第一个字符表示为1,然后将1+后续的字符串长度就得到了整个字符串的长度, str+1中str代表的是 h ,加1则代表后面一个字符 e ,让编译器从e开始计算,一直递归下去,直到*str = '\0' 返回其值可。
如果一开始读取的字符串就是'\0'则代表这个字符串长度为0,所以直接返回0即可,这样子我们就实现了不创建临时变量来计算字符串的长度,如图所示:
2023/8/17
王起舟