程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> The Standard C library 閱讀筆記(assert.h,ctype.h)

The Standard C library 閱讀筆記(assert.h,ctype.h)

編輯:關於C語言

assert.h

 assert宏定義的兩種表達方式:

  #define assert(exp) ((exp) ? (void)0 : _assert(msg))

  #define assert(exp) (void)( (exp) || _assert(msg))

ctype.h

1. 發展歷程:

  慣用法( if (0 <= c && c <= '9' ) ,使用頻繁程序過長且沒有利用好重用的代碼)  到

  函數區分字符類別( isalpha(c) 調用次數過頻,影響了程序的執行時間 ) 到

  宏定義(節約了執行時間,但是會遇到一些問題)

2. 宏定義可能會產生的問題

  • 程序員編寫的代碼量雖然小,但是編譯後的代碼量很大
  • 子表達式存在捆綁不緊,可能被分割的問題
  • 參數可能會被執行不被期望的多次(如getc,putc,++,--等)

3. 使用轉換表

  字符c編入以_ctype命名的轉換表索引中。每個表項的不同位以索引字符為特征。如果任何一個和掩碼_XXXMARK相對應的位被設置了,那個字符就在測試的類別中。對所有正確的參數,宏展開成一個緊湊的非零表達式。

  _UPPER          0x1     /* upper case letter */
  _LOWER          0x2     /* lower case letter */
  _DIGIT          0x4     /* digit[0-9] */
  _SPACE          0x8     /* tab, carriage return, newline, */
                                 
  _PUNCT          0x10    /* punctuation character */
  _CONTROL        0x20    /* control character */
  _BLANK          0x40    /* space char */
  _HEX            0x80    /* hexadecimal digit */
 
  _LEADBYTE       0x8000                  /* multibyte leadbyte */
  _ALPHA          (0x0100|_UPPER|_LOWER)  /* alphabetic character */

 

 unsigned  *_pctype = _ctype+;     
 unsigned  *_pwctype = _ctype+;    
 
 unsigned  _ctype[] =         ,                      
         _CONTROL,               
         _CONTROL,               
         _CONTROL,               
         _CONTROL,               
         _CONTROL,               
         _CONTROL,               
         _CONTROL,               
         _CONTROL,               
         _CONTROL,               
         _SPACE+_CONTROL,        
         _SPACE+_CONTROL,        
         _SPACE+_CONTROL,        
         _SPACE+_CONTROL,        
         _SPACE+_CONTROL,        
         _CONTROL,               
         _CONTROL,               
         _CONTROL,               
         _CONTROL,               
         _CONTROL,               
         _CONTROL,               
         _CONTROL,               
         _CONTROL,               
         _CONTROL,               
         _CONTROL,               
         _CONTROL,               
         _CONTROL,               
         _CONTROL,               
         _CONTROL,               
         _CONTROL,               
         _CONTROL,               
         _CONTROL,               
         _CONTROL,               
         _SPACE+_BLANK,          
         _PUNCT,                 
         _PUNCT,                 
         _PUNCT,                 
         _PUNCT,                 
         _PUNCT,                 
         _PUNCT,                 
         _PUNCT,                 
         _PUNCT,                 
         _PUNCT,                 
         _PUNCT,                 
         _PUNCT,                 
         _PUNCT,                 
         _PUNCT,                 
         _PUNCT,                 
         _PUNCT,                 
         _DIGIT+_HEX,            
         _DIGIT+_HEX,            
         _DIGIT+_HEX,            
         _DIGIT+_HEX,            
         _DIGIT+_HEX,            
         _DIGIT+_HEX,            
         _DIGIT+_HEX,            
         _DIGIT+_HEX,            
         _DIGIT+_HEX,            
         _DIGIT+_HEX,            
         _PUNCT,                 
         _PUNCT,                 
         _PUNCT,                 
         _PUNCT,                 
         _PUNCT,                 
         _PUNCT,                 
         _PUNCT,                 
         _UPPER+_HEX,            
         _UPPER+_HEX,            
         _UPPER+_HEX,            
         _UPPER+_HEX,            
         _UPPER+_HEX,            
         _UPPER+_HEX,            
         _UPPER,                 
         _UPPER,                 
         _UPPER,                 
         _UPPER,                 
         _UPPER,                 
         _UPPER,                 
         _UPPER,                 
         _UPPER,                 
         _UPPER,                 
         _UPPER,                 
         _UPPER,                 
         _UPPER,                 
         _UPPER,                 
         _UPPER,                 
         _UPPER,                 
         _UPPER,                 
         _UPPER,                 
         _UPPER,                 
         _UPPER,                 
         _UPPER,                 
         _PUNCT,                 
         _PUNCT,                 
         _PUNCT,                 
         _PUNCT,                 
         _PUNCT,                 
         _PUNCT,                 
         _LOWER+_HEX,            
         _LOWER+_HEX,            
         _LOWER+_HEX,            
         _LOWER+_HEX,            
         _LOWER+_HEX,            
         _LOWER+_HEX,            
         _LOWER,                 
         _LOWER,                 
         _LOWER,                 
         _LOWER,                 
         _LOWER,                 
         _LOWER,                 
         _LOWER,                 
         _LOWER,                 
         _LOWER,                 
         _LOWER,                 
         _LOWER,                 
         _LOWER,                 
         _LOWER,                 
         _LOWER,                 
         _LOWER,                 
         _LOWER,                 
         _LOWER,                 
         _LOWER,                 
         _LOWER,                 
         _LOWER,                 
         _PUNCT,                 
         _PUNCT,                 
         _PUNCT,                 
         _PUNCT,                 
         _CONTROL,               
         
 };

 

  isalpha(_c)     ( _pctype[_c] & (_UPPER|_LOWER) )
  isupper(_c)     ( _pctype[_c] & _UPPER )
  islower(_c)     ( _pctype[_c] & _LOWER )
  isdigit(_c)     ( _pctype[_c] & _DIGIT )
  isxdigit(_c)    ( _pctype[_c] & _HEX )
  isspace(_c)     ( _pctype[_c] & _SPACE )
  ispunct(_c)     ( _pctype[_c] & _PUNCT )
  isalnum(_c)     ( _pctype[_c] & (_UPPER|_LOWER|_DIGIT) )
  isprint(_c)     ( _pctype[_c] & (_BLANK|_PUNCT|_UPPER|_LOWER|_DIGIT) )
  isgraph(_c)     ( _pctype[_c] & (_PUNCT|_UPPER|_LOWER|_DIGIT) )
  iscntrl(_c)     ( _pctype[_c] & _CONTROL )
 _tolower(_c)    ( (_c)-'A'+'a' )
 _toupper(_c)    ( (_c)-'a'+'A' )

 

4. 轉換表可能遇到的問題

  這種方法的弊端是,對於某些錯誤的參數,宏會產生錯誤的代碼。如果一個宏的參數不在它的定義域內,那麼執行這個宏時,它就會訪問轉換表之外的存儲空間。

  如當測試某些比較生僻的字符代碼時,若符號位被置為,那麼參數會是一個負數,在函數的定義域之外。

  對於EOF符號,也要慎重處理。

  書上貌似沒有提對於轉換表實現方式的遇到問題的解決方案 -_-|||

5. 區域設置

  當區域設置改變時,我們的字符分類也可能會發生相應的改變。

6.靜態存儲空間

  庫可以使用指向表的指針的可寫的靜態存儲空間,但我們不能在程序中不同控制線程中共享一個相同的數據對象。

  上面的實現沒有使用靜態存儲空間。

7.實踐的實現中都是使用宏的嗎?

不小心看到mingw的實現並不是用的宏,代碼如下:

 __ISCTYPE(c, mask)  (MB_CUR_MAX == 1 ? (_pctype[c] & mask) : _isctype(c, mask)) __cdecl __MINGW_NOTHROW isalnum( c) { __ISCTYPE(c, (_ALPHA| __cdecl __MINGW_NOTHROW isalpha( c) { __cdecl __MINGW_NOTHROW iscntrl( c) { __cdecl __MINGW_NOTHROW isdigit( c) { __cdecl __MINGW_NOTHROW isgraph( c) { __ISCTYPE(c, (_PUNCT|_ALPHA| __cdecl __MINGW_NOTHROW islower( c) { __cdecl __MINGW_NOTHROW isprint( c) { __ISCTYPE(c, (_BLANK|_PUNCT|_ALPHA| __cdecl __MINGW_NOTHROW ispunct( c) { __cdecl __MINGW_NOTHROW isspace( c) { __cdecl __MINGW_NOTHROW isupper( c) { __cdecl __MINGW_NOTHROW isxdigit( c) { __ISCTYPE(c, _HEX);}

使用了內聯函數的實現,相對於宏更加安全了,另外把預處理的工作交給了編譯器,讓編譯器在代碼量和代碼效率間自動進行抉擇。

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