我的strcat:
*strcat( *dest, * * reval = (* dest++ (* *dest++ = *src++ *dest = * }
MSVC:
* * * * cp = ( * cp++; ( *cp++ = *src++ ) ; ( dst ); }
在while( *cp++ = *src++ )中,條件的值為賦值語句的返回值即*cp被賦的值,也就是此時*src的值。則,當*src為0時,將其賦給*cp後完成賦值。非常簡潔。
該函數的前提條件:src和dest所指內存區域不可以重疊且dest必須有足夠的空間來容納src的字符串。
我的strncat:
*strncat( *dest, *src, * reval = (* dest++ (n-- && (*dest++ = *src++ (n < *dest = }
MSVC:
* * * *start = (*front++ front-- (count-- (!(*front++ = *back++ *front = }
我的strchr:
*strchr( *s, (* (*s == s++ }
MSVC:
* * (* && * != ( ++ (* == ( (( *) }
我的strcmp:
strcmp( *s1, * (*s1 == *s2 && * ++s1 ++s2 *(unsigned *)s1 - *(unsigned * }
MSVC:
* * ret = ( ! (ret = *(unsigned *)src - *(unsigned *)dst) && * ++src, ++ ( ret < ret = - ( ret > ret = }
strcmp返回值不必為1和-1的。使用unsigned char 因為有符號數可能會導致比較大小錯誤。
我的strcpy:
*strcpy( *dest, * * reval = (*dest++ = *src++ }
MSVC:
* __cdecl strcpy( * dst, * * cp = ( *cp++ = *src++ ; }
我的strncpy:
*strncpy( *dest, *src, * reval = (n-- (* *dest++ = *src++ *dest++ = }
MSVC:
* * * *start = (count && (*dest++ = *source++)) count-- (count) (-- *dest++ = }
我的strcspn:
strcspn( *s1, * * reval = (; *s1; s1++ (cp = s2; *cp; cp++ (*s1 == * ++ }
MSVC:
* * unsigned *str = unsigned *ctrl = unsigned map[ (count=; count<; count++ map[count] = (* map[*ctrl >> ] |= ( << (*ctrl & ctrl++ count= map[] |= ; (!(map[*str >> ] & ( << (*str & count++ str++ }
返回值:返回字符串s 開頭連續不含字符串reject 內的字符數目。
我的實現和《C標准庫》書中基本相同,不需要任何的額外存儲空間,但是使用兩層的循環,花費較多的時間。
該函數的實質其實是判斷s1中的每一個字符,是否在s2字符串中,對於這種判斷是否在其中的問題,經常會采用映射表的方式來縮減查找時間,典型實現就是布隆過濾器。
此處,MSVC的實現就是采用了映射表的方式。
因為ASCII碼有256個,所以需要256bit來作為映射標記。一個字節是8bit,所以需要32個字節。所以在代碼中有 unsigned char map[32]的定義。
那麼,我們就需要將8bit,分別映射出一個map的下標和bit中的位位置。
map的下表需要使用5bit(32),而bit中的位位置使用剩余的3bit(8)來映射。
通過*ctrl >> 3取到高5位到0-31的映射,通過1 << (*ctrl & 7)取得到1字節中某一位的標記。
完成控制字符的映射表建立,就能用o(1)的時間完成某個字符的查找了。
strerror
功 能: 返回指向錯誤信息字符串的指針
例如:
#include <stdio.h> #include <errno.h> main( * buffer = printf( }
此段代碼strerror指向的內存中的字符串為No Error
我的strlen:
strlen( * *cp = (* cp++ (cp - }
MSVC:
* *eos = ( *eos++ ( ()(eos - str - }
返回值應該不需要強制類型轉換,因為指針相減返回值是int。當然,加上顯式轉換則更加明確。
ptrdiff_t
This is the type returned by the subtraction operation between two pointers. This is a signed integral type, and as such can be casted to compatible fundamental data types.
strpbrk和strspn的實現和strcspn相同
我的strrchr:
*strrchr( *str, *cp = (*str == (* str++ (*cp++ (*--str == }
MSVC:
* * *start = ( *) (*++) (-- != start && * != ( (* == ()ch) ( ( *) }
確實只需要初始位置的拷貝,不需要用拷貝來計數。
strtok,沒想好如何實現比較合適。
MSVC:
* * * unsigned * unsigned *ctrl = unsigned map[ * (count = ; count < ; count++ map[count] = map[*ctrl >> ] |= ( << (*ctrl & } (*ctrl++ ( str = str = ( (map[*str >> ] & ( << (*str & ))) && * str++ = ( ; *str ; str++ ( map[*str >> ] & ( << (*str & *str++ = nextoken = ( == }
用一個static變量來記錄當前分割到的位置,它是線程不安全的,多次調用也會使它失效。
strcoll使用當前的區域設置來比較字符串,strxfrm使用當前的區域設置來轉換字符串。當前區域設置由LL_COLLATE宏指定。它們均調用帶有區域設置參數的內部版本strcoll_l和strxfrm_l來完成實際的工作。
完