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 }

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM