程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> 走進C標准庫(8)——"string.h"中函數的實現相關字符串操作函數

走進C標准庫(8)——"string.h"中函數的實現相關字符串操作函數

編輯:關於C語言

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

 

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved