亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > .NET > 正文

C標準庫源碼解剖(6):字符串處理函數string.h和wchar.h(續)

2024-07-10 13:27:16
字體:
來源:轉載
供稿:網友

8、特定區域的字符串比較和轉換strcoll,strxfrm,wcscoll,wcsxfrm:strcoll使用當前的區域設置來比較字符串,strxfrm使用當前的區域設置來轉換字符串。當前區域設置由LL_COLLATE宏指定。它們均調用帶有區域設置參數的內部版本strcoll_l和strxfrm_l來完成實際的工作。

 

[cpp] view plaincopy
  1. /* strcoll.c:strcoll函數的實現 */  
  2. #include <string.h>  
  3. #ifndef STRING_TYPE  
  4. # define STRING_TYPE char  
  5. # define STRCOLL strcoll  
  6. # define STRCOLL_L __strcoll_l  
  7. # define USE_HIDDEN_DEF  
  8. #endif  
  9. #include "../locale/localeinfo.h"  
  10. int  
  11. STRCOLL (s1, s2)  
  12.      const STRING_TYPE *s1;  
  13.      const STRING_TYPE *s2;  
  14. {  
  15.   return STRCOLL_L (s1, s2, _NL_CURRENT_LOCALE);  
  16. }  
  17. #ifdef USE_HIDDEN_DEF  
  18. libc_hidden_def (STRCOLL)  
  19. #endif  

 

 

[cpp] view plaincopy
  1. /* strxfrm.c:strxfrm函數的實現  */  
  2. #include <string.h>  
  3. #include <locale/localeinfo.h>  
  4. #ifndef STRING_TYPE  
  5. # define STRING_TYPE char  
  6. # define STRXFRM strxfrm  
  7. # define STRXFRM_L __strxfrm_l  
  8. #endif  
  9. size_t  
  10. STRXFRM (STRING_TYPE *dest, const STRING_TYPE *src, size_t n)  
  11. {  
  12.   return STRXFRM_L (dest, src, n, _NL_CURRENT_LOCALE);  
  13. }  

 

    9、錯誤消息報告strerror:獲取錯誤碼errnum的字符串描述,在下一次調用strerror之前這個字符串存儲空間不能修改,對這個空間進行寫操作會導致未定義的行為。若獲取沒有成功,則使用errno全局變量(或全局宏)中的錯誤碼來獲取錯誤消息。

 

[cpp] view plaincopy
  1. /* strerror.c:strerror函數的實現  */  
  2. #include <libintl.h> /* 有很多內部接口 */  
  3. #include <stdio.h>  
  4. #include <string.h>  
  5. #include <errno.h>   /* errno中保存了程序的錯誤碼 */  
  6. /* 返回錯誤碼errnum的字符串描述,在下一次調用strerror之前這個字符串存儲 
  7.     空間不能修改,對這個空間進行寫操作會導致未定義的行為 */  
  8. libc_freeres_ptr (static char *buf); /* 存放字符串描述的全局空間 */  
  9. char *  
  10. strerror (errnum)  
  11.      int errnum;  
  12. {  
  13.   char *ret = __strerror_r (errnum, NULL, 0); /* 根據錯誤碼獲取錯誤消息 */  
  14.   int saved_errno;  
  15.   if (__builtin_expect (ret != NULL, 1)) /* 若錯誤消息獲取成功,則返回它 */  
  16.     return ret;  
  17.   /* 否則獲取errno中保存的程序錯誤碼,用緩沖區buf來存儲它的字符串描述 */  
  18.   saved_errno = errno;  
  19.   if (buf == NULL)  
  20.     buf = malloc (1024);  /* buf是一個全局緩沖區 */  
  21.   __set_errno (saved_errno); /* 設置錯誤碼 */  
  22.   if (buf == NULL)  
  23.     return _("Unknown error");  
  24.   return __strerror_r (errnum, buf, 1024); /* 獲取錯誤碼對應的錯誤消息并返回 */  
  25. }  

 

    10、內存塊復制memcpy,memmove,wmemcpy,wmemmove:memcpy從SRC中復制N個字節的內容到DEST中,memmove從SRC中復制N個字節的內容到DEST中,保證對重疊字符串(即SRC與DEST共用存儲空間)有正確的行為。這兩個函數的實現使用了memcopy.h和pagecopy.h中定義的內部接口,有按字節方式復制BYTE_COPY_FWD,按字方式復制WORD_COPY_FWD(一個字為unsigned long型)、按頁方式復制PAGE_COPY_FWD_MAYBE,這些接口都是以宏的形式提供的。

 

[cpp] view plaincopy
  1. /* memcopy.h -- 在內存復制函數中使用的一些定義  */  
  2. /* 內存函數的復制策略是: 
  3.      1、復制字節,直到目標指針被對齊。 
  4.      2、在展開的循環中復制字。如果源指針和目標指針不是用 
  5.       同一種方式對齊,則使用字內存操作,但在寫之前要對兩個讀取的字進行移位和合并 
  6.      3、復制剩下的幾個字節 
  7.      在至少有10個寄存器用來給GCC使用的處理器上,這是非常快速的,并且能在一條指令中使用 
  8.     reg+const來訪問內存  */  
  9. #include <sys/cdefs.h>  
  10. #include <endian.h>  
  11. /* 在本文件中定義的宏有: 
  12.    BYTE_COPY_FWD(dst_beg_ptr, src_beg_ptr, nbytes_to_copy) 
  13.    BYTE_COPY_BWD(dst_end_ptr, src_end_ptr, nbytes_to_copy) 
  14.    WORD_COPY_FWD(dst_beg_ptr, src_beg_ptr, nbytes_remaining, nbytes_to_copy) 
  15.    WORD_COPY_BWD(dst_end_ptr, src_end_ptr, nbytes_remaining, nbytes_to_copy) 
  16.    MERGE(old_word, sh_1, new_word, sh_2) 
  17. */  
  18. /* 用于對齊的內存操作類型,正常時它應該是能一次裝載和存儲的最大類型 */  
  19. #define op_t    unsigned long int  
  20. #define OPSIZ   (sizeof(op_t))  
  21. /* 用于未對齊的操作類型 */  
  22. typedef unsigned char byte;  
  23. /* 用于在寄存器中存儲字節的優化類型 */  
  24. #define reg_char    char  
  25. /* 對兩個字的合并操作 */  
  26. #if __BYTE_ORDER == __LITTLE_ENDIAN  /* 小端字節序:w0在低端,w1在高端 */  
  27. #define MERGE(w0, sh_1, w1, sh_2) (((w0) >> (sh_1)) | ((w1) << (sh_2)))  
  28. #endif  
  29. #if __BYTE_ORDER == __BIG_ENDIAN  /* 大端字節序:w0在高端,w1在低端 */  
  30. #define MERGE(w0, sh_1, w1, sh_2) (((w0) << (sh_1)) | ((w1) >> (sh_2)))  
  31. #endif  
  32. /* 向前復制:從SRC_BP中精確地復制NBTYES個字節到DST_BP中,無需對指針的對齊作任何假設  */  
  33. #define BYTE_COPY_FWD(dst_bp, src_bp, nbytes)                     /  
  34.   do                                          /  
  35.     {                                         /  
  36.       size_t __nbytes = (nbytes);                         /  
  37.       while (__nbytes > 0)                             /  
  38.     {                                     /  
  39.       byte __x = ((byte *) src_bp)[0];                    /  
  40.       src_bp += 1;                                /  
  41.       __nbytes -= 1;                              /  
  42.       ((byte *) dst_bp)[0] = __x;                         /  
  43.       dst_bp += 1;                                /  
  44.     }                                     /  
  45.     } while (0)  
  46. /* 向后復制:從SRC_END_PTR中精確地復制NBTYTES_TO_COPY個字節到DST_END_PTR中, 
  47.     復制從指針前面的字節右端開始,并且向著更小的地址方向前進。無需對指針的對齊作任何假設 */  
  48. #define BYTE_COPY_BWD(dst_ep, src_ep, nbytes)                     /  
  49.   do                                          /  
  50.     {                                         /  
  51.       size_t __nbytes = (nbytes);                         /  
  52.       while (__nbytes > 0)                             /  
  53.     {                                     /  
  54.       byte __x;                               /  
  55.       src_ep -= 1;                                /  
  56.       __x = ((byte *) src_ep)[0];                         /  
  57.       dst_ep -= 1;                                /  
  58.       __nbytes -= 1;                              /  
  59.       ((byte *) dst_ep)[0] = __x;                         /  
  60.     }                                     /  
  61.     } while (0)  
  62. /* 向前復制:從SRC_BP中復制最多NBYTES個字節到DST_BP中,假設DST_BP對齊到OPSIZ的倍數。 
  63.     如果不是所有的字節都能順利的復制,剩下的字節數保存到NBYTES_LEFT中,否則存入0 */  
  64. extern void _wordcopy_fwd_aligned (long intlong intsize_t) __THROW;  
  65. extern void _wordcopy_fwd_dest_aligned (long intlong intsize_t) __THROW;  
  66. #define WORD_COPY_FWD(dst_bp, src_bp, nbytes_left, nbytes)            /  
  67.   do                                          /  
  68.     {                                         /  
  69.       if (src_bp % OPSIZ == 0)                            /  
  70.     _wordcopy_fwd_aligned (dst_bp, src_bp, (nbytes) / OPSIZ);         /  
  71.       else                                    /  
  72.     _wordcopy_fwd_dest_aligned (dst_bp, src_bp, (nbytes) / OPSIZ);        /  
  73.       src_bp += (nbytes) & -OPSIZ;                        /  
  74.       dst_bp += (nbytes) & -OPSIZ;                        /  
  75.       (nbytes_left) = (nbytes) % OPSIZ;                       /  
  76.     } while (0)  
  77. /* 向后復制:從SRC_END_PTR中復制最多NBYTES_TO_COPY個字節到DST_END_PTR中,復制 
  78.     從指針前面的字(為op_t類型)的右端開始,并且向著更小的地址方向前進。可以利用DST_END_PTR 
  79.     已經對齊到OPSIZ的倍數。如果不是所有的字節都能順利的復制,剩下的字節數保存到 
  80.     NBYTES_REMAINING中,否則存入0 */  
  81. extern void _wordcopy_bwd_aligned (long intlong intsize_t) __THROW;  
  82. extern void _wordcopy_bwd_dest_aligned (long intlong intsize_t) __THROW;  
  83. #define WORD_COPY_BWD(dst_ep, src_ep, nbytes_left, nbytes)            /  
  84.   do                                          /  
  85.     {                                         /  
  86.       if (src_ep % OPSIZ == 0)                            /  
  87.     _wordcopy_bwd_aligned (dst_ep, src_ep, (nbytes) / OPSIZ);         /  
  88.       else                                    /  
  89.     _wordcopy_bwd_dest_aligned (dst_ep, src_ep, (nbytes) / OPSIZ);        /  
  90.       src_ep -= (nbytes) & -OPSIZ;                        /  
  91.       dst_ep -= (nbytes) & -OPSIZ;                        /  
  92.       (nbytes_left) = (nbytes) % OPSIZ;                       /  
  93.     } while (0)  
  94. /* 進入展開循環的門檻值  */  
  95. #define OP_T_THRES  16  

 

 

[cpp] view plaincopy
  1. /* pagecopy.h -- 按頁方式來復制的宏;用在memcpy和memmove中  */  
  2. /* 本文件中定義的宏: 
  3.    PAGE_COPY_FWD_MAYBE (dstp, srcp, nbytes_left, nbytes) 
  4.     由WORD_COPY_FWD以及其他的函數來調用,指針至少要是字對齊的。這將會檢查虛頁復制是否能 
  5.     執行、是否應該執行、以及如果能執行的話則執行它 
  6.     依賴于系統的pagecopy.h文件應該定義以下宏,然后包含本文件: 
  7.    PAGE_COPY_THRESHOLD 
  8.    -- 值得使用按頁復制策略的最小字節數 
  9.    PAGE_SIZE 
  10.    -- 頁的大小 
  11.    PAGE_COPY_FWD (dstp, srcp, nbytes_left, nbytes) 
  12.    -- 執行虛頁復制操作的宏。指針要對齊到PAGE_SIZE個字節的邊界上 
  13. */  
  14. #if PAGE_COPY_THRESHOLD  
  15. #include <assert.h>  
  16. #define PAGE_COPY_FWD_MAYBE(dstp, srcp, nbytes_left, nbytes)              /  
  17.   do                                          /  
  18.     {                                         /  
  19.       if ((nbytes) >= PAGE_COPY_THRESHOLD &&                   /  
  20.       PAGE_OFFSET ((dstp) - (srcp)) == 0)                     /  
  21.     {                                     /  
  22.       /* 要復制的字節數超過內核用于復制虛擬頁的VM操作的門檻值,且源地址         / 
  23.          和目標地址有同樣的對齊方式 */    /  
  24.       size_t nbytes_before = PAGE_OFFSET (-(dstp));               /  
  25.       if (nbytes_before != 0)                         /  
  26.         {                                     /  
  27.           /* 首先復制第一頁前面的各個字  */     /  
  28.           WORD_COPY_FWD (dstp, srcp, nbytes_left, nbytes_before);         /  
  29.           assert (nbytes_left == 0);                      /  
  30.           nbytes -= nbytes_before;                        /  
  31.         }                                     /  
  32.       PAGE_COPY_FWD (dstp, srcp, nbytes_left, nbytes);            /  
  33.     }                                     /  
  34.     } while (0)  
  35. /* 頁大小總是2的冪,這樣我們就可以避免模除法運算  */  
  36. #define PAGE_OFFSET(n)  ((n) & (PAGE_SIZE - 1))  
  37. #else  
  38. #define PAGE_COPY_FWD_MAYBE(dstp, srcp, nbytes_left, nbytes)   
  39. #endif  

 

 

[cpp] view plaincopy
  1. /* memcpy.c:memcpy函數的實現  */  
  2. #include <string.h>  
  3. #include <memcopy.h>  /* 包含了字節復制函數BYTE_COPY_FWD和字復制函數WORD_COPY_FWD */  
  4. #include <pagecopy.h>  /* 包含內存頁復制函數PAGE_COPY_FWD_MAYBE */  
  5. #undef memcpy  
  6. /* 從src中復制len個字節的內容到dst中  */  
  7. void *  
  8. memcpy (dstpp, srcpp, len)  
  9.      void *dstpp;  
  10.      const void *srcpp;  
  11.      size_t len;  
  12. {  
  13.   unsigned long int dstp = (long int) dstpp;  
  14.   unsigned long int srcp = (long int) srcpp;  
  15.   /* 從開始復制到末尾 */  
  16.   /* 如果len足夠長,使用字復制方式(一個字為long類型,一般占4個字節) */  
  17.   if (len >= OP_T_THRES)  
  18.     {  
  19.       /* 復制開頭的幾個字節,以使dstp對齊到字的邊界 */  
  20.       len -= (-dstp) % OPSIZ;  
  21.       BYTE_COPY_FWD (dstp, srcp, (-dstp) % OPSIZ); /* 字節復制方式 */  
  22.       /* 通過虛擬地址操作,從srcp中復制盡可能多的頁到dstp中 */  
  23.       PAGE_COPY_FWD_MAYBE (dstp, srcp, len, len); /* 頁復制方式 */  
  24.       /* 利用對齊的dstp,采用字復制方式從srcp復制到dstp。剩余的字節數放在第三個實參中, 
  25.             例如放在len中。這個數字可能在不同的機器有不同的值 */  
  26.       WORD_COPY_FWD (dstp, srcp, len, len);  
  27.       /* 復制剩下的尾部幾個字節 */  
  28.     }  
  29.   /* 還有剩下的幾個字節,使用字節內存操作  */  
  30.   BYTE_COPY_FWD (dstp, srcp, len);  
  31.   return dstpp;  
  32. }  
  33. libc_hidden_builtin_def (memcpy)  

 

 

[cpp] view plaincopy
  1. /* memmove.c:memmove函數的實現 */  
  2. #include <string.h>  
  3. #include <memcopy.h>  /* 包含了字節復制函數BYTE_COPY_FWD和字復制函數WORD_COPY_FWD */  
  4. #include <pagecopy.h>  /* 包含內存頁復制函數PAGE_COPY_FWD_MAYBE */  
  5. /* 所有這些都是為了在定義了一些東西后bcopy.c能包含本文件 */  
  6. #ifndef a1  
  7. #define a1  dest    /* 第一個實參是dest */  
  8. #define a1const  
  9. #define a2  src     /* 第二個實參是src  */  
  10. #define a2const const  
  11. #undef memmove  
  12. #endif  
  13. #if !defined(RETURN) || !defined(rettype)  
  14. #define RETURN(s)   return (s)  /* 返回dest  */  
  15. #define rettype     void *  
  16. #endif  
  17. /* 從SRC中復制LEN個字節的內容到DEST中,保證對重疊字符串(即SRC與DEST共用存儲空間)有正確的行為 */  
  18. rettype  
  19. memmove (a1, a2, len)  
  20.      a1const void *a1;  
  21.      a2const void *a2;  
  22.      size_t len;  
  23. {  
  24.   unsigned long int dstp = (long int) dest;  
  25.   unsigned long int srcp = (long int) src;  
  26.   /* 這個測試使得向前復制代碼一旦可能就能被使用,減少工作集 */  
  27.   if (dstp - srcp >= len)    /* *Unsigned* compare!  */  
  28.     {  
  29.       /* 從開始復制到末尾 */  
  30.       /* 如果len足夠長,使用字復制方式(一個字為long類型,一般占4個字節) */  
  31.       if (len >= OP_T_THRES)  
  32.     {  
  33.       /* 復制開頭的幾個字節,以使dstp對齊到字的邊界 */  
  34.       len -= (-dstp) % OPSIZ;  
  35.       BYTE_COPY_FWD (dstp, srcp, (-dstp) % OPSIZ); /* 字節復制方式 */  
  36.       /* 通過虛擬地址操作,從srcp中復制盡可能多的頁到dstp中 */  
  37.       PAGE_COPY_FWD_MAYBE (dstp, srcp, len, len); /* 頁復制方式 */  
  38.       /* 利用對齊的dstp,采用字復制方式從srcp復制到dstp。剩余的字節數放在第三個實參中, 
  39.             例如放在len中。這個數字可能在不同的機器有不同的值 */  
  40.       WORD_COPY_FWD (dstp, srcp, len, len);  
  41.       /* 復制剩下的尾部幾個字節 */  
  42.     }  
  43.       /* 還有剩下的幾個字節,使用字節內存操作 */  
  44.       BYTE_COPY_FWD (dstp, srcp, len);  
  45.     }  
  46.   else  
  47.     {  
  48.       /* 從開始復制到末尾  */  
  49.       srcp += len;  
  50.       dstp += len;  
  51.       /* 如果len足夠長,使用字復制方式(一個字為long類型,一般占4個字節) */  
  52.       if (len >= OP_T_THRES)  
  53.     {  
  54.       /* 復制開頭的幾個字節,以使dstp對齊到字的邊界 */  
  55.       len -= dstp % OPSIZ;  
  56.       BYTE_COPY_BWD (dstp, srcp, dstp % OPSIZ);  
  57.       /* 利用對齊的dstp,采用字復制方式從srcp復制到dstp。剩余的字節數放在第三個實參中, 
  58.             例如放在len中。這個數字可能在不同的機器有不同的值 */  
  59.       WORD_COPY_BWD (dstp, srcp, len, len);  
  60.       /* 復制剩下的尾部幾個字節 */  
  61.     }  
  62.       /* 還有剩下的幾個字節,使用字節內存操作 */  
  63.       BYTE_COPY_BWD (dstp, srcp, len);  
  64.     }  
  65.   RETURN (dest);  
  66. }  
  67. #ifndef memmove  
  68. libc_hidden_builtin_def (memmove)  
  69. #endif  

 

    解釋:
    (1)memcopy.h中,宏op_t為字的類型,定義為unsigned long,OPSIZ為字的大小(32位平臺中為4字節)。byte為字節的類型,定義為unsigned char。MERGE函數用于合并兩個字,根據不同的機器字節序,一個字在高端,一個字在低端。字節復制和字復制都有兩種方式,一種是向前復制,一種是向后復制。字復制時需要指針對齊到字的邊界(即指針變量中的值為OPSIZ的倍數),復制操作使用了編譯器內置的_wordcopy_fwd_aligned等函數。字節復制的接口中的代碼是很直接的,用一個while循環一個字節一個字節地進行拷貝即可。宏OP_T_THRES定義了能進行字復制的最低門檻值。
    (2)pagecopy.h中,要復制的字節數必須達到一定的門檻值PAGE_COPY_THRESHOLD(這個值在內核中定義),才會執行按頁復制。PAGE_SIZE為頁的大小,在內核中定義,PAGE_OFFSET(n)用于計算頁的偏移。復制時先用WORD_COPY_FWD復制前面幾個字節,這樣就能讓源地址和目標地址按頁對齊,然后就可執行頁復制。
    (3)有了這些宏,memcpy和memmove函數的實現就比較簡單了,直接用這些接口來進行復制操作,只不過要注意進行字復制或頁復制時要復制開頭的幾個字節,以對齊到字或頁的邊界。最后尾部可能還剩下幾個字節,用字節復制復制它們即可。   
    11、內存塊中的字符搜索memchr,wmemchr:在內存塊S的前N個字節中搜索C的第一次出現。算法實現與strlen及strchr類似。

 

[cpp] view plaincopy
  1. /* memchr.c:memchr函數的實現 */  
  2. #ifdef HAVE_CONFIG_H  
  3. #include <config.h>  
  4. #endif  
  5. #undef __ptr_t  
  6. /* 標準C++或標準C中通用指針為void*類型 */  
  7. #if defined (__cplusplus) || (defined (__STDC__) && __STDC__)  
  8. # define __ptr_t void *  
  9. #else /* 傳統C中通用指針為char*類型 */  
  10. # define __ptr_t char *  
  11. #endif  
  12. #if defined _LIBC  
  13. # include <string.h>  
  14. # include <memcopy.h>  
  15. #else  
  16. # define reg_char char  
  17. #endif  
  18. #if HAVE_STDLIB_H || defined _LIBC  
  19. # include <stdlib.h>  
  20. #endif  
  21. #if HAVE_LIMITS_H || defined _LIBC  
  22. # include <limits.h>  
  23. #endif  
  24. #define LONG_MAX_32_BITS 2147483647  
  25. #ifndef LONG_MAX  
  26. #define LONG_MAX LONG_MAX_32_BITS  
  27. #endif  
  28. #include <sys/types.h>  
  29. #if HAVE_BP_SYM_H || defined _LIBC  
  30. #include <bp-sym.h>  
  31. #else  
  32. # define BP_SYM(sym) sym  
  33. #endif  
  34. #undef memchr  
  35. #undef __memchr  
  36. /* 在S的前N個字節中搜索C的第一次出現  */  
  37. __ptr_t  
  38. __memchr (s, c_in, n)  
  39.      const __ptr_t s;  
  40.      int c_in;  
  41.      size_t n;  
  42. {  
  43.   const unsigned char *char_ptr;  
  44.   const unsigned long int *longword_ptr;  
  45.   unsigned long int longword, magic_bits, charmask;  
  46.   unsigned reg_char c;  
  47.   c = (unsigned char) c_in;  
  48.   /* 通過一次讀取一個字符來處理開頭的幾個字符,直到char_ptr中的值對齊到一個long型字的邊界, 
  49.       即直到char_ptr中的值是long的字節數(通常為4)的倍數 */  
  50.   for (char_ptr = (const unsigned char *) s;  
  51.        n > 0 && ((unsigned long int) char_ptr  
  52.          & (sizeof (longword) - 1)) != 0;  
  53.        --n, ++char_ptr)  
  54.     if (*char_ptr == c)   /* 若到達字符c處,則直接返回其指針 */  
  55.       return (__ptr_t) char_ptr;  
  56.   /* 所有這些說明性的注釋使用4字節的long型字,但本算法同樣也可以應用于8字節的long型字 */  
  57.   longword_ptr = (unsigned long int *) char_ptr;  
  58.   /* magic_bits的第8,16,24,31位為0,稱這些位為“洞”。注意每個字節的左邊有一個洞, 
  59.       在最后的位置上也有一個洞。 
  60.      bits:  01111110 11111110 11111110 11111111 
  61.       比特1確保進位能傳播到后面的比特0上,比特0則提供洞,以便讓進位陷進去  */  
  62.   if (sizeof (longword) != 4 && sizeof (longword) != 8)  
  63.     abort ();  
  64. #if LONG_MAX <= LONG_MAX_32_BITS  
  65.   magic_bits = 0x7efefeff;  
  66. #else  
  67.   magic_bits = ((unsigned long int) 0x7efefefe << 32) | 0xfefefeff;  
  68. #endif  
  69.   /* 設置一個長整型字,其每個字節都是字符c */  
  70.   charmask = c | (c << 8);  
  71.   charmask |= charmask << 16;  
  72. #if LONG_MAX > LONG_MAX_32_BITS  
  73.   charmask |= charmask << 32;  
  74. #endif  
  75.   /* 這里我們不使用傳統的對每個字符都進行測試的循環,而是一次測試一個long型字。技巧性的部分 
  76.       是測試當前long型字的各個字節是否為0 */  
  77.   while (n >= sizeof (longword))  
  78.     {      
  79.       /* longword中有一個字節為C,恰好等價于longword ^ charmask中有一個字節為0 */  
  80.       longword = *longword_ptr++ ^ charmask;  
  81.       /* 讓longword加上魔數magic_bits  */  
  82.       if ((((longword + magic_bits)  
  83.         /* 設置那些通過加法而未改變的位 */  
  84.         ^ ~longword)  
  85.        /* 只需看這些洞。如果任何的洞位都沒有改變,最有可能的是有一個字節值為C或者到達終止符處(沒找到C) */  
  86.        & ~magic_bits) != 0)  
  87.     {  
  88.       /* 長整型字的哪個字節為C或0?如果都不是,則是一個非預期情況,繼續搜索 */  
  89.       const unsigned char *cp = (const unsigned char *) (longword_ptr - 1);  
  90.       if (cp[0] == c)  
  91.         return (__ptr_t) cp;  
  92.       if (cp[1] == c)  
  93.         return (__ptr_t) &cp[1];  
  94.       if (cp[2] == c)  
  95.         return (__ptr_t) &cp[2];  
  96.       if (cp[3] == c)  
  97.         return (__ptr_t) &cp[3];  
  98. #if LONG_MAX > 2147483647      /* 如果long類型是8個字節,則還有4個字節需要判斷 */  
  99.       if (cp[4] == c)  
  100.         return (__ptr_t) &cp[4];  
  101.       if (cp[5] == c)  
  102.         return (__ptr_t) &cp[5];  
  103.       if (cp[6] == c)  
  104.         return (__ptr_t) &cp[6];  
  105.       if (cp[7] == c)  
  106.         return (__ptr_t) &cp[7];  
  107. #endif  
  108.     }  
  109.       n -= sizeof (longword);  
  110.     }  
  111.   /* 循環完如果還剩下幾個字節,則繼承搜索這剩下的幾個字節 */  
  112.   char_ptr = (const unsigned char *) longword_ptr;  
  113.   while (n-- > 0)  
  114.     {  
  115.       if (*char_ptr == c)  
  116.     return (__ptr_t) char_ptr;  
  117.       else  
  118.     ++char_ptr;  
  119.     }  
  120.   return 0;  
  121. }  
  122. #ifdef weak_alias  
  123. weak_alias (__memchr, BP_SYM (memchr))  
  124. #endif  
  125. libc_hidden_builtin_def (memchr)  

 

    12、內存塊比較memcmp,wmemcmp:對兩個內存塊的前N個字節進行比較。比較也是使用字(unsigned long型)的比較方式,以加快搜索速度。采用的策略是先比較開頭的幾個字節,以使塊指針對齊到字的邊界,再用memcmp_common_alignment(兩個內存塊都對齊的情況)或memcmp_not_common_alignment(一個內存塊對齊,而另一個沒有對齊)按字進行快速的比較,最后對剩下的幾個字節進行比較。代碼就不再解剖了,涉及到大量的字操作,以及用MERGE進行字合并(這需要考慮到機器的字節序)。     
    13、內存塊設置memset,wmemset:將內存塊的前LEN個字節設置為字符C。也是采用字的方式來進行快速地寫入。先設置了一個字cccc,其每個字節都是字符C。為了加快寫入速度,每循環一次就寫入8個cccc,最后對剩下的幾個字節寫入C。

 

[cpp] view plaincopy
  1. /* memset.c:memset函數的實現  */  
  2. #include <string.h>  
  3. #include <memcopy.h>  
  4. #undef memset  
  5. /* 將內存塊DST的前LEN個字節設置為字符C */  
  6. void *  
  7. memset (dstpp, c, len)  
  8.      void *dstpp;  
  9.      int c;  
  10.      size_t len;  
  11. {  
  12.   long int dstp = (long int) dstpp;  
  13.   if (len >= 8)  
  14.     {  
  15.       size_t xlen;  
  16.       op_t cccc;  
  17.         
  18.       /* 設置一個長整型字,其每個字節都是字符c */  
  19.       cccc = (unsigned char) c;  
  20.       cccc |= cccc << 8;  
  21.       cccc |= cccc << 16;  
  22.       if (OPSIZ > 4)  
  23.       /* 移位操作分兩步,以避免當long為32位時出現警告 */  
  24.     cccc |= (cccc << 16) << 16;  
  25.      /* 把dstp對齊到字的邊界,開頭的幾個字節要設置為C,在這個對齊循環中無需 
  26.          測試LEN是否等于0 */  
  27.       while (dstp % OPSIZ != 0)  
  28.     {  
  29.       ((byte *) dstp)[0] = c;  
  30.       dstp += 1;  
  31.       len -= 1;  
  32.     }  
  33.       /* 每次迭代中寫8個op_t型的字,直到剩下不到8個字為止 */  
  34.       xlen = len / (OPSIZ * 8); /* 計算迭代次數 */  
  35.       while (xlen > 0)  
  36.     {  
  37.       ((op_t *) dstp)[0] = cccc;  
  38.       ((op_t *) dstp)[1] = cccc;  
  39.       ((op_t *) dstp)[2] = cccc;  
  40.       ((op_t *) dstp)[3] = cccc;  
  41.       ((op_t *) dstp)[4] = cccc;  
  42.       ((op_t *) dstp)[5] = cccc;  
  43.       ((op_t *) dstp)[6] = cccc;  
  44.       ((op_t *) dstp)[7] = cccc;  
  45.       dstp += 8 * OPSIZ;  
  46.       xlen -= 1;  
  47.     }  
  48.       len %= OPSIZ * 8; /* 計算剩下的字節數 */  
  49.       /* 每次迭代寫1個字,直到剩下不到OPSIZ個字節為止 */  
  50.       xlen = len / OPSIZ;  /* 計算迭代次數 */  
  51.       while (xlen > 0)  
  52.     {  
  53.       ((op_t *) dstp)[0] = cccc;  
  54.       dstp += OPSIZ;  
  55.       xlen -= 1;  
  56.     }  
  57.       len %= OPSIZ;  
  58.     }  
  59.   /* 寫入最后剩下的幾個字節 */  
  60.   while (len > 0)  
  61.     {  
  62.       ((byte *) dstp)[0] = c;  
  63.       dstp += 1;  
  64.       len -= 1;  
  65.     }  
  66.   return dstpp;  
  67. }  
  68. libc_hidden_builtin_def (memset)  

 

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
91免费看片网站| 91麻豆桃色免费看| 精品日本美女福利在线观看| 国产精品第3页| 欧美精品久久一区二区| 国产91精品黑色丝袜高跟鞋| 久久久久久久久久久久av| 国产欧美日韩综合精品| 亚洲欧美国内爽妇网| 日韩av影院在线观看| 久久久亚洲网站| 91精品国产91久久| 九九热在线精品视频| 亚洲2020天天堂在线观看| 中文字幕亚洲专区| 91在线免费观看网站| 国产精品揄拍一区二区| 欧美在线免费观看| 国产91精品最新在线播放| 亚洲一区二区三区乱码aⅴ蜜桃女| 66m—66摸成人免费视频| 亚洲夜晚福利在线观看| 日韩av网址在线| xxxx欧美18另类的高清| 国产精品视频不卡| 日韩va亚洲va欧洲va国产| 欧美精品做受xxx性少妇| 欧美成人三级视频网站| 久热精品视频在线免费观看| 在线观看日韩欧美| 日韩精品中文字幕在线观看| 亚洲影院污污.| 欧美资源在线观看| 伊人伊成久久人综合网小说| 在线播放日韩专区| 在线成人激情视频| 久久精品国亚洲| 日韩乱码在线视频| 亚洲欧美日韩一区二区三区在线| 成人免费网站在线| 亚洲自拍小视频免费观看| 欧美又大又硬又粗bbbbb| 日韩中文av在线| 亚洲乱码一区av黑人高潮| 中文字幕国产日韩| 热久久视久久精品18亚洲精品| 国产欧美日韩中文字幕在线| 久久亚洲电影天堂| 欧美精品videosex极品1| 欧美视频一区二区三区…| 国产精品专区第二| 日本精品在线视频| 中文字幕亚洲欧美日韩高清| 国产欧美日韩视频| 国产精品久久久久久久久久久新郎| 成人网中文字幕| 中文字幕欧美在线| 久久九九亚洲综合| 亚洲男人天堂网站| 精品国产老师黑色丝袜高跟鞋| 亚洲第一页在线| 欧美成人网在线| 久久国产精品久久久久久久久久| 中文字幕一区日韩电影| 久久人人爽人人爽人人片av高清| 欧美日韩加勒比精品一区| 亚洲天堂av高清| 亚洲欧美制服丝袜| 精品久久久久国产| 国产精品日韩精品| 久久久久久久影视| 九九九久久国产免费| 中文字幕少妇一区二区三区| 中文字幕亚洲在线| 亚洲欧美另类国产| 亚洲小视频在线| 91麻豆国产语对白在线观看| 欧美视频一区二区三区…| 久久久久久久久爱| 亚洲精品动漫久久久久| 国产一区二区在线播放| 成人黄在线观看| 亚洲一区二区精品| 97色在线视频观看| 久热精品视频在线| 国产在线观看一区二区三区| 欧美大片免费观看在线观看网站推荐| 日韩激情av在线播放| 国产精品海角社区在线观看| 高清一区二区三区日本久| 日韩成人av一区| 精品国产自在精品国产浪潮| 色婷婷综合久久久久| 午夜精品久久久久久99热软件| 亚洲va欧美va国产综合久久| 欧美丝袜第一区| 亚洲精品福利在线观看| 精品美女国产在线| 精品亚洲国产成av人片传媒| 国外成人在线视频| 欧美超级免费视 在线| 91日本在线观看| 97在线看免费观看视频在线观看| 97高清免费视频| 欧美老肥婆性猛交视频| 国产精品久久久久久av下载红粉| 亚洲国产91精品在线观看| 亚洲第一网站免费视频| 亚洲女成人图区| 欧美电影在线观看网站| 久久久女人电视剧免费播放下载| 日韩欧美在线第一页| 国产精品欧美激情| 91免费看片在线| 亚洲激情自拍图| 国产精品999999| 国产精品小说在线| 日韩美女av在线免费观看| 日韩国产欧美精品一区二区三区| 亚洲精品www久久久久久广东| 97在线精品国自产拍中文| 国产视频精品一区二区三区| 国产香蕉一区二区三区在线视频| 成人性生交大片免费看小说| 亚洲精品中文字幕av| 日韩av网址在线观看| 91在线免费网站| 国产精品视频xxxx| 欧美日韩日本国产| 成人国产在线激情| 亚洲欧美一区二区三区在线| 欧美极品在线视频| 日本免费一区二区三区视频观看| 日韩久久午夜影院| 亚洲精品电影网站| 日韩电影大全免费观看2023年上| 日韩欧美成人免费视频| 亚洲国产免费av| 欧美日韩国产一区二区三区| 精品亚洲aⅴ在线观看| 91色琪琪电影亚洲精品久久| 欧美日韩激情小视频| 欧美日韩国产va另类| 欧美日韩国产一区中文午夜| 中文字幕视频在线免费欧美日韩综合在线看| 日产精品99久久久久久| 欧美极品少妇xxxxx| 欧美高清不卡在线| 91精品国产乱码久久久久久蜜臀| 亚洲一区中文字幕在线观看| 国产成人啪精品视频免费网| 日韩69视频在线观看| 亚洲影院色无极综合| 国产一区二区三区中文| 26uuu另类亚洲欧美日本一| 日韩中文字幕精品视频| 亚洲欧美资源在线| 国产精品久久中文| 日韩在线视频网| 懂色av一区二区三区| 国产做受高潮69| 久久久久久九九九| 色悠悠久久久久| 欧美理论片在线观看|