我的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來完成實際的工作。
完