當前位置:首頁 » 操作系統 » strlen源碼

strlen源碼

發布時間: 2022-07-04 02:58:07

① 為什麼有時候要在strlen前加上(int)將其化為int型,而有的時候不加

strlen()
原型:extern
unsigned
int
strlen(char
*s);,在Visual
C++
6.0中,原型為size_t
strlen(
const
char
*string
);,其中size_t實際上是unsigned
int,在VC6中可以看到源碼:typedef
unsigned
int
size_t;。
頭文件:string.h
功能:計算字元串s的(unsigned
int型)長度
說明:返回s的長度,不包括結束符NULL。
返回的是size_t型,也就是unsigned
int型,表示的范圍是比int更大的。
但一般情況下int都是OK的啦。所以加與不加,大多數情況下都沒啥問題,除非超過了int的表示範圍。

c語言strlen函數問題

strlen實際上是,從參數表示的地址往後找,找到第一個'',即串尾。然後計算''至首地址的「距離」,即隔了幾個字元,從而得出長度。

char x[]={0xBC,0xDD,0xCA};中,實際上是定義了一個char型的數組,而由於x[0],即0xBC開始往後找,一直到0xCA,都沒'',所以會繼續往後。當然,實際上往後找到的是其他值。

改char x[]={0xBC,0xDD,0xCA,0x00};後,應該就是3了。

(2)strlen源碼擴展閱讀:

strlen所作的僅僅是一個計數器的工作,它從內存的某個位置(可以是字元串開頭,中間某個位置,甚至是某個不確定的內存區域)開始掃描,直到碰到第一個字元串結束符''為止,然後返回計數器值(長度不包含'')。

函數原型

extern unsigned int strlen(char *s);

在Visual C++ 6.0或Dev-C++中,原型為

size_t strlen(const char *string);

,其中size_t實際上是unsigned int,在VC6.0或Dev-C++中可以看到這樣的代碼:

typedef unsigned int size_t;

頭文件:string.h或cstring

格式:strlen (字元數組名)

功能:計算給定字元串的(unsigned int型)長度,不包括''在內

說明:返回s的長度,不包括結束符NULL。

參考資料:strlen-網路

php的count(數組)和strlen(字元串)的內部實現。

翻了下PHP內核的定義,大概心中也有了答案了

count()和strlen()都是O(1)的時間復雜度

試想一下如果strlen()需要O(N)的復雜度那未免也太慢了,字元串長度起來的話伺服器不是要直接掛掉嗎

這兩個函數都是典型的空間換時間的做法

我們可以先看看zvalue的結構:

typedefunion_zvalue_value{
longlval;/*longvalue*/
doubledval;/*doublevalue*/
struct{
char*val;
intlen;
}str;
HashTable*ht;/*hashtablevalue*/
zend_object_valueobj;
zend_ast*ast;
}zvalue_value;

這里用的是一個聯合體,當變數類型是string類型的時候附加存儲多了一個len的整型變數,顯而易見需要取長度直接利用記錄值就可以了,自然就是O(1)

對於count()常用的參數類型應該為數組,對於繼承Countable的類暫不作討論

數組實現方式為Hashtable,直接看看他的結構吧

typedefstruct_hashtable{
uintnTableSize;//hashBucket的大小,最小為8,以2x增長。
uintnTableMask;//nTableSize-1,索引取值的優化
uintnNumOfElements;//hashBucket中當前存在的元素個數,count()函數會直接返回此值
ulongnNextFreeElement;//下一個數字索引的位置
Bucket*pInternalPointer;//當前遍歷的指針(foreach比for快的原因之一)
Bucket*pListHead;//存儲數組頭元素指針
Bucket*pListTail;//存儲數組尾元素指針
Bucket**arBuckets;//存儲hash數組
dtor_func_tpDestructor;//在刪除元素時執行的回調函數,用於資源的釋放
zend_boolpersistent;//指出了Bucket內存分配的方式。如果persisient為TRUE,則使用操作系統本身的內存分配函數為Bucket分配內存,否則使用PHP的內存分配函數。
unsignedcharnApplyCount;//標記當前hashBucket被遞歸訪問的次數(防止多次遞歸)
zend_boolbApplyProtection;//標記當前hash桶允許不允許多次訪問,不允許時,最多隻能遞歸3次
#ifZEND_DEBUG
intinconsistent;
#endif
}HashTable;

count直接獲取nNumOfElements大小,所以也是O(1)

補充------------------------------------------------

count() 函數的定義在這里

/*{{{protointcount(mixedvar[,intmode])
(usuallyanarray)*/
PHP_FUNCTION(count)
{
zval*array;
zend_longmode=COUNT_NORMAL;
zend_longcnt;
zval*element;

ZEND_PARSE_PARAMETERS_START(1,2)
Z_PARAM_ZVAL(array)
Z_PARAM_OPTIONAL
Z_PARAM_LONG(mode)
ZEND_PARSE_PARAMETERS_END();

switch(Z_TYPE_P(array)){
caseIS_NULL:
php_error_docref(NULL,E_WARNING,"");
RETURN_LONG(0);
break;
caseIS_ARRAY:
if(mode!=COUNT_RECURSIVE){
//類型為數組時調用zend內核函數zend_array_count()
cnt=zend_array_count(Z_ARRVAL_P(array));
}else{
cnt=php_count_recursive(Z_ARRVAL_P(array));
}
RETURN_LONG(cnt);
break;
caseIS_OBJECT:{
zvalretval;
/*first,wecheckifthehandlerisdefined*/
if(Z_OBJ_HT_P(array)->count_elements){
RETVAL_LONG(1);
if(SUCCESS==Z_OBJ_HT(*array)->count_elements(array,&Z_LVAL_P(return_value))){
return;
}
}
/*()method*/
if(instanceof_function(Z_OBJCE_P(array),zend_ce_countable)){
zend_call_method_with_0_params(array,NULL,NULL,"count",&retval);
if(Z_TYPE(retval)!=IS_UNDEF){
RETVAL_LONG(zval_get_long(&retval));
zval_ptr_dtor(&retval);
}
return;
}

/*IfThere'snohandleranditdoesn'*/
php_error_docref(NULL,E_WARNING,"");
RETURN_LONG(1);
break;
}
default:
php_error_docref(NULL,E_WARNING,"");
RETURN_LONG(1);
break;
}
}

如果沒有特別指定mode參數為 COUNT_RECURSIVE 的話(即作遍歷),跳轉到 zend 的數組計數函數 zend_array_count()

#definezend_hash_num_elements(ht)
(ht)->nNumOfElements

...
...

staticuint32_tzend_array_recalc_elements(HashTable*ht)
{
zval*val;
uint32_tnum=ht->nNumOfElements;

ZEND_HASH_FOREACH_VAL(ht,val){
if(Z_TYPE_P(val)==IS_INDIRECT){
if(UNEXPECTED(Z_TYPE_P(Z_INDIRECT_P(val))==IS_UNDEF)){
num--;
}
}
}ZEND_HASH_FOREACH_END();
returnnum;
}

ZEND_APIuint32_tzend_array_count(HashTable*ht)
{
uint32_tnum;
if(UNEXPECTED(ht->u.v.flags&HASH_FLAG_HAS_EMPTY_IND)){
num=zend_array_recalc_elements(ht);
if(UNEXPECTED(ht->nNumOfElements==num)){
ht->u.v.flags&=~HASH_FLAG_HAS_EMPTY_IND;
}
}elseif(UNEXPECTED(ht==&EG(symbol_table))){
num=zend_array_recalc_elements(ht);
}else{
num=zend_hash_num_elements(ht);
}
returnnum;
}

IS_REFERENCE:間接 zval 指的就是其真正的值是存儲在其他地方的。注意這個IS_REFERENCE類型是不同的,間接 zval 是直接指向另外一個 zval 而不是像zend_reference結構體一樣嵌入 zval。

只有當數組中有HASH_FLAG_HAS_EMPTY_IND 這個 flag 時(間接zval)才會對數組進行遍歷校驗,其他情況下都是直接取 數組(hash table) 裡面的 nNumOfElements 的值,答案顯而易見了,就是O(1)

④ C語言實現strlen函數的幾種方法

今天偶然看到了一個實現strlen函數的方法,也實際練習了一下,挺有意義的,其實現的一些思想值得學習,記錄一下吧。我這里除了寫兩個比較巧妙的遞歸實現之外,也寫了另外一種常規的方式。 傳說常見的一個筆試題:不使用中間變數求const字元串長度,即實現求字元串長度庫函數strlen函數。函數介面聲明如下:int strlen(const char *p); 思路分析: 在字元串中通常可以利用最後一個結束符』\0』,但此處參數為const,只讀,那麼我們不能打他的主意。 函數運行過程中不佔用內存基本不可能,除非都使用了寄存器。「不使用中間變數」只是說程序員不能顯示的申請內存而已,即不能有局部變數或者動態內存申請。 如果函數自動申請棧內存或者使用寄存器存儲變數,或者使用立即數定址即常量,那麼就相當於「不使用中間變數」。 從函數原型看,返回值為int,那麼在函數內部必定需要一個地方存儲這個值,要麼是常數要麼是寄存器。長度不為1時不能一次就求出來,說明必須有遞歸調用,這樣遞歸時函數會自動申請棧內存,這樣就相當於程序員「不使用中間變數」了。中間返回的值通過寄存器自動保存,最後一次返回時拷貝到int中去。C/C++中也有臨時對象的概念,都是程序在運行過程中由編譯器在棧中自動申請的對象,對程序員不可見,也相當於「不使用中間變數」 另外一個不申請任何變數的典型題目是:反轉字元串 這種問題都是利用常量,或者將變數的申請交給編譯器在遞歸過程中自動在棧中申請,也就是借刀殺人了。 無代碼,無真相;簡單的源碼如下:#include #include #include int myStrlen(const char *str); int myStrlen1(const char *str); int myStrlen2(const char *str);int main(){char *str=NULL; str = "Hello Jay!";

⑤ 小弟用的是codeblocks,想查看一些函數的源代碼,例如strlen,在codeblocks如

比較挫的方法,在錯誤提示頁面跳轉,比如strlen(),你可以在調用時故意不寫參數,然後編譯器提示錯誤,這時你就可以在錯誤欄中進行跳轉,如圖:(小白一個,不太清楚其他好方法)

⑥ char a[20]="abcd\0def"的長度

strlen(a)==4
sizeof(a)==20

strlen函數是一個c編譯庫函數,他的作用是計算a中字元個數,計算方式是遇到\0結束運算。
strlen函數在vc7中的庫函數源碼如下:
size_t __cdecl strlen (
const char * str
)
{
const char *eos = str;

while( *eos++ ) ;

return( (int)(eos - str - 1) );
}
而sizeof是c中計算某變數佔用空間位元組數的關鍵字,在這里數組a被定義為20個位元組型數據,因此sizeof(a)==20

⑦ 求C語言中strlen()函數的源代碼

unsigned int strlen(const char *s)
{
int len = 0;
while(*s++)
len++;
return len;
}

⑧ 用指針編寫字元串處理函數:字元串復制函數strcpy,比較函數strcmp,連接函數strcat,長度計算函數strlen。

這些函數的源碼上網隨便都能找到,這不難。你似乎還需要寫個界面?用C/C++的話,那就先輸出提示內容,然後讓用戶輸入1234,讀取用戶的輸入,調用相應的函數。
求採納為滿意回答。

⑨ strlen 函數的源代碼

代碼源為:

int Strlen(const char * const s)

{

int i;

for (i = 0; s[i]; i++) ;

return i;

}

(9)strlen源碼擴展閱讀:

注意事項

原型:extern unsigned int strlen(char *s);

頭文件:string.h

格式:strlen (字元數組名)

功能:計算字元串s的(unsigned int型)長度,不包括''在內

說明:返回s的長度,不包括結束符NULL。

例如:

#include <string.h>

#include<stdio.h>

intmain(void)

{

char*s="Golden Global View";

printf("%s has %d chars",s,strlen(s));

getchar();

return0;

}
熱點內容
hp存儲擴容 發布:2024-11-17 23:29:16 瀏覽:568
在ftp中put表示什麼 發布:2024-11-17 23:29:12 瀏覽:382
mvc多文件上傳 發布:2024-11-17 23:13:56 瀏覽:153
玩游戲硬碟緩存32m 發布:2024-11-17 23:03:42 瀏覽:523
藍光存儲系統 發布:2024-11-17 23:03:41 瀏覽:436
地平線4提示配置低於最低怎麼辦 發布:2024-11-17 22:54:38 瀏覽:609
注冊銀行卡賬戶密碼填什麼 發布:2024-11-17 22:54:35 瀏覽:535
java壓縮上傳圖片 發布:2024-11-17 22:26:59 瀏覽:627
plc編程課件 發布:2024-11-17 22:18:23 瀏覽:469
我的世界伺服器信號一直在檢測 發布:2024-11-17 22:09:52 瀏覽:547