strlen函数实现的几种方法
常见的一个笔试题:不使用中间变量求const字符串长度,即实现求字符串长度库函数strlen函数。函数接口声明如下:
1 int strlen(const char *p);
在字符串中通常可以利用最后一个结束符’\0’,但此处参数为const,只读,那么我们不能打他的主意。
函数运行过程中不占用内存基本不可能,除非都使用了寄存器。“不使用中间变量”只是说程序员不能显示的申请内存而已,即不能有局部变量或者动态内存申请。
如果函数自动申请栈内存或者使用寄存器存储变量,或者使用立即数寻址即常量,那么就相当于“不使用中间变量”。
从函数原型看,返回值为int,那么在函数内部必定需要一个地方存储这个值,要么是常数要么是寄存器。长度不为1时不能一次就求出来,说明必须有递归调用,这样递归时函数会自动申请栈内存,这样就相当于程序员“不使用中间变量”了。中间返回的值通过寄存器自动保存,最后一次返回时拷贝到int中去。C/C++中也有临时对象的概念,都是程序在运行过程中由编译器在栈中自动申请的对象,对程序员不可见,也相当于“不使用中间变量”
另外一个不申请任何变量的典型题目是:反转字符串
这种问题都是利用常量,或者将变量的申请交给编译器在递归过程中自动在栈中申请,也就是借刀杀人了。
无代码,无真相;简单的源码如下:
1 #include "stdafx.h" 2 #include <stdio.h> 3 #include <string.h> 4 #include <assert.h> 5 6 int myStrlen(const char *str); 7 int myStrlen1(const char *str); 8 int myStrlen2(const char *str); 9 10 int main() 11 { 12 char *str=NULL; 13 str = "Hello world!"; 14 printf("original strlen():%d\n",strlen(str)); 15 printf("myStrlen():%d\n",myStrlen(str)); 16 printf("myStrlen1():%d\n",myStrlen1(str)); 17 printf("myStrlen2():%d\n",myStrlen2(str)); 18 } 19 20 int myStrlen(const char *str) /* 不用中间变量,用递归实现,很容易看懂 */ 21 { 22 if ( (str == NULL) || (*str == '\0') ) { 23 return 0; 24 } 25 else { 26 return myStrlen(str+1)+1; 27 } 28 } 29 30 int myStrlen1(const char *str) /* 不用中间变量,也是用递归实现,写得更简洁而已 */ 31 { 32 assert(str != NULL); 33 return *str ? (myStrlen1(++str) + 1) : 0; 34 } 35 36 int myStrlen2(const char *str) /* 使用了一个int型变量 */ 37 { 38 if(str==NULL) return 0; 39 int len = 0; 40 for(; *str++ != '\0'; ) 41 { 42 len++; 43 } 44 return len; 45 }
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步