在php中String是經常使用的類型,今天就開始閱讀他的函數,本人小菜,有什麼錯誤的地方望大神指點。php
首先string的函數定義在/ext/standard/string.c文件中,這裏我看的php版本是php7.1.2。c++
首先在對於php源碼中的函數,定義方法都是PHP_FUNCTION(方法名稱)算法
這兩個函數的源碼相對比較簡單,可是在文件中既出現 PHPAPI char *php_strtoupper(char *s, size_t len) 又出現了 PHPAPI zend_string *php_string_toupper(zend_string *s) 他們代碼的主要算法是同樣的,可是在定於strtoupper方法處是這樣寫的
PHP_FUNCTION(strtoupper) { zend_string *arg; ZEND_PARSE_PARAMETERS_START(1, 1) Z_PARAM_STR(arg) ZEND_PARSE_PARAMETERS_END(); RETURN_STR(php_string_toupper(arg)); }
因此函數應該是php_string_toupper,至於php_strtoupper,由檢索得這個函數多是爲內部一些方法提供的接口
PHPAPI zend_string *php_string_toupper(zend_string *s) { unsigned char *c, *e; //c是字符串的起始位置,e是字符串的結束位置 c = (unsigned char *)ZSTR_VAL(s); //返回zeng_tring類型中數據部分val的值,也就是字符串的首地址 e = c + ZSTR_LEN(s); //由於是e定義的是指針類型,因此e的地址就是字符串的首地址+字符串長度,也就是'\0'的地址 //這裏使用到了COW,也就是寫是拷貝 while (c < e) { if (islower(*c)) { register unsigned char *r; zend_string *res = zend_string_alloc(ZSTR_LEN(s), 0); //定義res 併爲res申請地址空間 if (c != (unsigned char*)ZSTR_VAL(s)) { //判斷c是不是原始字符串的首地址 memcpy(ZSTR_VAL(res), ZSTR_VAL(s), c - (unsigned char*)ZSTR_VAL(s)); // 若是c地址不是原始字符串首地址, //則從原始字符串的首地址開始--->當前c指向的字符串地址,這部分地址數據複製給res r = c + (ZSTR_VAL(res) - ZSTR_VAL(s)); //定義開始字符大小轉換的標記,也就是從哪一個地址開始進行字符串轉換 while (c < e) { //這裏就很簡單了 *r = toupper(*c); r++; c++; } *r = '\0'; //定義字符串結束符 return res; } c++; } return zend_string_copy(s); //若是整個字符串沒有須要轉換的字符,則將字符串的引用計數+1 }
這裏須要說明的是,ZSTR_VAL是返回zeng_string結構體類型的數據部分的val值
struct _zend_string { zend_refcounted_h gc; zend_ulong h; /* hash value */ size_t len; char val[1]; 就是這個值 };
同理 ZSTR_LEN是返回len值php7
- ###strtolower和strtoupper###
先暫時寫到這裏,後續有時間繼續補充。。。。。函數