C語言的缺陷與陷阱 札記 七 可移植性缺陷

2021-09-11 06:37:03 字數 2295 閱讀 9614

how to write protable software in c

有些c實現將所有字元作為有效字元;

有些c自動擷取長字元的尾部;

ansi標準規定,識別符號可以為任意長度,但外部名必須至少能由前6個字元唯一地區分,並且不              區分大小寫;

例如:print_float   &   print_fileds    *****  可能帶來為危險!

state  &   state  ***** 這樣的命名方式不明智!

malloc & malloc  ***** 可能導致不可預知的境地!

short  <  int  <  long        

乙個普通(int 型別)整數足夠容納任何陣列下標

字元長度有硬體特性決定 《大多數機器字元長度是8位》

大多數計算機將8位字元當做8位整數處理,但是,並非所有編譯器都按照8位整數來解釋這些字元——這涉及符號位的解釋與處理!當將乙個字元轉為較大(8bit以上)整數時候,問題變得棘手!!!

例如 :char  -----> int 需要合理的處理掉符號位!!!   -128~127   vs   0~255

例如 :char  c  直接使用(unsigned) c 是不能得到與c等價的無符號整數的!因為 其真實的轉換過程是   -----    c >>> int >>> unsigned c

1、向右移位,空出的位置由 0 還是 符號位の副本填充?

無符號的一定用0填充;有符號的具體採用什麼由c語言的具體實現決定!!!

2、移位計數(移位操作的位數)允許最大範圍?

必須嚴格控制的bit_width以內!!!

3、向左移位,符號位符合處理,保留麼?

null 只能不指向任何物件。因此除了賦值和比較運算,其他任何使用null指標的都是非法!!!

例如:strcmp(null,null) 是嚴重危險的

--- 有的c對記憶體位置0做了硬體級的讀保護,錯誤使用將立刻停止;

--- 有的c對記憶體位置0只允許讀;

--- 有的c對記憶體位置0不做任何處理》極端危險!!!!!

q  = a/b;

r   = a%b;

這裡假設b!=0。

@1、q*b+r=a  餘數關係約束條件;

@2、改變a的正負號,希望q跟著改變,但是q的絕對值不變;

@3、如果b>0, 希望r>=0 且 r三個約束條件無法同時滿足,一般的c實現選擇支援1、2同時滿足!!!

早期的c在16位機器上實現隨機函式rand(0~2^15-1非負整數)。後來的機器發展到32位,研發人員則實現了rand(0~2^31-1非負整數)。

如此,則導致了移植的缺陷: 解決辦法是提供了乙個巨集 rand_max 來限定最大隨機數!!!

早期的庫函式 toupper  和  tolower 被定義為巨集

#define toupper(c)   ( (c) + 'a' - 'a' )

#define tolower(c)   ( (c)  + 'a' - 'a' )

危險之處在於如果c 傳入的大小寫不對!!!就會返回無效資訊!!!

因此一般用法: (  isupper(c)?tolower(c):c  )

為了避免,每次都預先檢測,進一步的改進是:

#define toupper(c)   ( (c) >= 『a』&&  (c) <= 'z'  ?  (c) + 'a' - 'a' : (c) )

#define tolower(c)    ( (c) >= 'a' && (c) <= 'z' ?  (c) + 'a' - 'a' : (c)  )

但是:如果 使用 toupper(*p++)這樣又會帶來重複計算的危險!!!

最終,採用了兩種實現方式,以便於靈活實現:

int toupper(int c)

if(c>='a' && c<='z')

return c+'a'-'a'

return c;

#define _toupper(c)   ( (c) + 'a' - 'a' )

tolowper 也 有類似實現!

malloc  realloc  free

realloc :  該函式指標 ptr 所指向記憶體的大小調整為size位元組,返回乙個指向調整後記憶體塊(可能改記憶體塊已經被移動過了)的指標。

假定原來是 oldsize  新的是 newsize, 那麼min(oldsize,newsize)中的內容保持不變!!!

C陷阱與缺陷 第七章 可移植性缺陷

注意不同的c 語言的實現,把乙個識別符號 現的所有字元都作為有效字元處理,還是自動階段乙個長的識別符號的名稱的尾部 同時注意不同的c 語言的實現,對大小寫字母的區分 c 語言中提供了 3 種不同長度的整數 short int,long,c 語言中的字元行為方式與小整數相似。c語言對各種不同型別的整數...

C語言陷阱與缺陷(5)

庫函式 1.返回整數的getchar函式 記住 getchar的返回型別為int 而不是char.2.更新順序檔案 乙個檔案輸入操作不能隨後緊跟乙個檔案輸出操作,反之亦然。若要同時進行檔案輸入 輸出操作,必須在其中插入 fseek函式的呼叫 用於改變檔案的狀態,使其能正常的讀取 3.緩衝輸出與記憶體...

C語言缺陷與陷阱(6)

預處理器 巨集 一種對組成 c程式的字元進行變換的方式,而並不作用於程式中的物件。1.不能忽視巨集定義中的空格 define f x x 1 被翻譯為 f 代表 x x 1 2.巨集並不是函式 巨集定義中最好把每個引數都用括號括起來,整個結果表示式也應該用括號括起來。要確保巨集中的引數沒有 如,引數...