strlen()函數也是一個經常用到的函數,今天就來實作一下它。
照例,依舊先建構整體架構:
#include <stdio.h> int main() { char arr[] = "hello world !"; int len = my_strlen(arr); printf("%d\n", len); return 0; }
下面就來具體實作了:
第一種:
第二種:int my_strlen(const char * src) { int len = 0; while (*src++ != '\0') ++len; //前置++(--)的效率不會低于後置++(--) return len; }
int my_strlen(const char * src) //因為不需要對src的内容進行改變,是以加上const修飾 { char *tmp = (char *)src; assert(src); //斷言src非空 while (*tmp) { //tmp指向src的結束标志的'\0' ++tmp; } return tmp - src; //位址相減,得到的實際是它們之間的元素個數 }
為了使用assert(),需要包含assert.h頭檔案。另外,說一下最後的兩個指針相減為什麼得到的是元素個數:
隻有當兩個指針都指向同一個數組中的元素時候,才允許一個指針減去另外一個指針。
![]()
strlen()函數自實作 1.兩個指針相減是這兩個指針之間元素的個數,而不是元素的長度。
2.如果兩個指針指向不同的數組中的元素,那麼它們之間相減的結果是未定義的。
标準規定:
允許指向數組元素的指針與指向數組最後一個元素後面的那個記憶體位置的指針比較,但不允許與指向數組第一個元素之前的那個記憶體位置的指針比較。
例如将一個數組進行初始化的代碼:
這是可以的,再如下:for (vp = &values[0]; vp < &values[N_VALUES];) { *vp++ = 0; }
或者把它再簡化一下:for (vp = &values[N_VALUES]; vp > &values[0];) { *--vp = 0; }
for (vp = &values[N_VALUES - 1]; vp >= &values[0]; vp--) { *--vp = 0; }
對後邊這兩段代碼(實際上是一樣的)實際在絕大部分的編譯器上是可以順利完成任務的,然而我們還是應該避免這樣寫,因為标準并不保證它可行。
第三種:
遞歸寫法。int my_strlen(const char *str) { assert(str); if ('\0' == *str) return 0; return 1 + my_strlen2(str + 1); }