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.巨集並不是函式 巨集定義中最好把每個引數都用括號括起來,整個結果表示式也應該用括號括起來。要確保巨集中的引數沒有 如,引數...