規範化的C 程式設計方法備忘錄 整數宣告

2021-05-22 06:02:25 字數 2020 閱讀 5831

形式上把整數分成3大類:

-通用型整數:int/long/short/char,及他們的unsigned型別

特點:標準位元組的寬度 | 用於大小有限,又不強調最大值,或者最大值總保證滿足實際需要的場合。

| 平台無關。不同的編譯器,同樣型別的整數,不同編譯器廠商規定的實際位元組的寬度可能不同,具體由編譯器廠商決定。

| 不要假定某個型別的具體位寬(除了char/unsigned char),不要假定最大值的具體數值。例如,不要以為int就是32位(儘管現在事實如此)。

-固定位寬:int8/int16/int32/int64; byte/word/dword/uint64注意有些編譯系統的庫只有第乙個字母大寫,或者全部小寫。

特點:指定位元組寬度 | 用於強調固定寬度的場合。

| 編譯器無關。平台無關 | 意義很明確:例如dword就是4位元組。

-指標型整數:size_t/diffmem_t/intptr_t/uintptr_t

特點:寬度等於指標寬度 | 常用於取得指標的比較結果、指標取值、通用混合型別變數的傳遞(vc.net之前版本不支援)。

| 編譯器無關。平台相關 | 不要假定具體位寬,不要假定最大值的具體數值。例如,不要以為size_t等於int位寬(儘管win32中如此)。

分類的目的:防止出現位相容性問題;方便編譯系統間、硬體平台間移植(如x86到x64)。

說明:

-對於編譯器及硬體來說只有一種型別:固定位寬。但這不妨礙我們分類。事實上開發人員面對的首先是型別庫而不是編譯器。乙個完善的編譯器應當給出完善的3種型別,而不是讓程式設計師自己寫平台轉換**。規範的**應當沒有移植性問題,這包括向乙個假設的編譯系統和硬體。應當確保最多隻需重新編譯而不用修改源**。

-指標型整數不是指標而是整數。

-如果我們看到編譯系統的標頭檔案有如下宣告:

不表示你也可以這樣做。你買一把鎖沒有自己做鑰匙的義務。

對於一些老程式設計師,很多規則顯得比較「新」而且怪異。不過幸運的是,「軟體牛仔的時代已經一去不復返了(對於某些人來說,也許是不幸的)」

規則:

a.以下不等式恆成立:

由以上可得出:

1 得到 sizeof(int) >= 2

1、4 得到 sizeof(void *) >= 2

注意這些公式給正確進行強制型別轉換的提示。要把不等式看成真正的不等式,不然你的**在不同硬體平台間移植時很可能會出問題(例如從win32移植到win64)。如果你的軟體**量很大,你的麻煩就大了。

有時候正規化的編譯器廠商也會自己提供一些自定義整數型別。例如微軟的dword_ptr保證在任意情況下都可同時容納乙個dword或者乙個指標型整數。所以不要寫了這麼久還不明白為什麼廠商要定義這麼多不同名的「其實是一回事」的整數型別。

b.無符號整數的賦值規範:

-窄型別可安全地賦值給寬型別

-寬型別賦值給窄型別需要強制型別轉換,而安全複製的前提是:你已經在原來的寬型別中證明了該轉換的值的適用性。

-不同大類間賦值總是需要強制型別轉換(除非滿足3/4/推論),且安全複製的前提是:如果某較寬整數按照你的實際應用要求(注意這種要求不應該依賴於平台)的取值範圍恆包含於較窄目標整數的取值範圍,則賦值可行,但必須進行強制型別轉換。

注意特殊情況的運用。例如下面是有問題的**:

int a;

lpctstr pc = "1", pd = "2";

a = pd - pc // here. the 'a' should be a size_t typed integer.

但下面的**卻可以:

int b = (int)sizeof(larg_integer); // that is right because the larg_integer always takes 8 bytes, which is small and will not be extended in future.

----------------------------

附議:

規範化的C 程式設計方法備忘錄 整數分類的細則

分類的選取 選取的原則是目的和取值範圍,另外對於多選的,還要考慮傳值的方便和盡量提高處理器效能。例1 宣告乙個變數n,用於儲存兩個任意指標間的差值 要達到任意指標間的差值都能被恰當的儲存,可知只有指標型整數能滿足要求。寫成 size t n 例2 乙個通用的記憶體分配函式被宣告為void alloc...

boiz 的 C 備忘錄(一)

本文主要是記錄一些初級的但是有時候我自己容易忽略或者忘記東西,僅作備忘錄之用。1 銜接符 在c 中可以作為銜接符 忘了規範的術語是不是這麼叫了,汗自己乙個 例如 this is memo this is memo too 上面兩行在c 中,編譯器會認為是一行。不過 一般只在巨集定義中使用,因為如果是...

boiz 的 C 備忘錄(二)

1 c 函式引數入棧順序 從右到左 下面的例子用來驗證c 函式引數入棧順序 void test int i1,int i2,int i3 printf i1 d,i2 d,i3 d n i1,i2,i3 int i 0 test i,i,i 則輸出結果為 i1 3,i2 2,i3 1 2 乙個有趣的...