【轉】C語言實現strlen函數的幾種方法


原文地址:http://www.51testing.com/html/72/n-221172.html

 

傳說常見的一個筆試題:不使用中間變量求const字符串長度,即實現求字符串長度庫函數strlen函數。函數接口聲明如下:int strlen(const char *p);

  思路分析:

  在字符串中通常可以利用最后一個結束符’\0’,但此處參數為const,只讀,那么我們不能打他的主意。

  函數運行過程中不占用內存基本不可能,除非都使用了寄存器。“不使用中間變量”只是說程序員不能顯示的申請內存而已,即不能有局部變量或者動態內存申請。

  如果函數自動申請棧內存或者使用寄存器存儲變量,或者使用立即數尋址即常量,那么就相當於“不使用中間變量”。

   從函數原型看,返回值為int,那么在函數內部必定需要一個地方存儲這個值,要么是常數要么是寄存器。長度不為1時不能一次就求出來,說明必須有遞歸調 用,這樣遞歸時函數會自動申請棧內存,這樣就相當於程序員“不使用中間變量”了。中間返回的值通過寄存器自動保存,最后一次返回時拷貝到int中去。 C/C++中也有臨時對象的概念,都是程序在運行過程中由編譯器在棧中自動申請的對象,對程序員不可見,也相當於“不使用中間變量”

  另外一個不申請任何變量的典型題目是:反轉字符串

  這種問題都是利用常量,或者將變量的申請交給編譯器在遞歸過程中自動在棧中申請,也就是借刀殺人了。

  無代碼,無真相;簡單的源碼如下:

#include <stdio.h>
#include <string.h>
#include <assert.h>

int myStrlen(const char *str);
int myStrlen1(const char *str);
int myStrlen2(const char *str);

int main()
{
    char *str=NULL;
    str = "Hello Jay!";
    printf("original strlen():%d\n",strlen(str));
    printf("myStrlen():%d\n",myStrlen(str));
    printf("myStrlen1():%d\n",myStrlen1(str));
    printf("myStrlen2():%d\n",myStrlen2(str));
}

int myStrlen(const char *str)   /* 不用中間變量,用遞歸實現,很容易看懂 */
{
    if ( (str == NULL) || (*str == '\0') ) {
        return 0;
    }
    else {
        return myStrlen(str+1)+1;
    }
}

int myStrlen1(const char *str)  /* 不用中間變量,也是用遞歸實現,寫得更簡潔而已 */
{
    assert(str != NULL);
    return *str ? (myStrlen1(++str) + 1) : 0;
}

int myStrlen2(const char *str)  /* 使用了一個int型變量 */
{
    if(str==NULL) return 0;
    int len = 0;
    for(; *str++ != '\0'; )
    {
        len++;
    }
    return len;
}

 

 


免責聲明!

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



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