 基礎(chǔ)數(shù)據(jù)類型、常量const與#define工程取舍)
承接上文上一節(jié)我們完整拆解 HelloWorld 程序理清預(yù)處理?編譯?匯編?鏈接完整流程搞懂頭文件、main 入口、命名空間的基礎(chǔ)規(guī)則。本節(jié)進(jìn)入 C 最底層的數(shù)據(jù)存儲基礎(chǔ)內(nèi)置數(shù)據(jù)類型同時辨析兩套常量寫法const和#define站在初級工程師工程視角講清什么時候該用哪一個避開新手常見混用坑。學(xué)習(xí)說明跳過極少用到的古老奇葩類型只保留業(yè)務(wù)開發(fā)高頻內(nèi)置類型不堆砌教科書式表格重點(diǎn)講內(nèi)存大小、取值邊界、工程選擇、踩坑點(diǎn)。本節(jié)學(xué)習(xí)目標(biāo)掌握 C 常用基礎(chǔ)內(nèi)置類型整型、浮點(diǎn)、字符、布爾理解各自內(nèi)存占用與適用場景分清有符號 / 無符號整型的風(fēng)險看懂溢出帶來的隱性 BUG理解字面量、變量、常量三者概念區(qū)別掌握const常量用法理解編譯期特性看懂#define宏常量的本質(zhì)理清工程上 const 與 #define 的取舍原則識別類型溢出、無符號負(fù)數(shù)、宏替換陷阱等高頻工程問題完整參考代碼一、C 基礎(chǔ)內(nèi)置數(shù)據(jù)類型1. 整型系列保存整數(shù)int最常用整型4 字節(jié)業(yè)務(wù)開發(fā)首選存儲正負(fù)整數(shù)short短整型2 字節(jié)內(nèi)存極度受限場景才考慮普通業(yè)務(wù)極少使用long long長整型8 字節(jié)處理大數(shù)必須優(yōu)先使用避免 int 溢出無符號版本unsigned int、unsigned long long只能存非負(fù)數(shù)??工程坑點(diǎn) 無符號類型賦值負(fù)數(shù)不會編譯報錯會發(fā)生隱式轉(zhuǎn)換得到一個巨大正數(shù)產(chǎn)生隱蔽 BUG 示例unsigned int x -1;最終 x 的實(shí)際值為4294967295 日常業(yè)務(wù)代碼盡量少用無符號除非明確處理位、字節(jié)、數(shù)組長度場景。2. 浮點(diǎn)類型保存小數(shù)float單精度4 字節(jié)精度有限適合對精度不敏感、追求內(nèi)存占用場景double雙精度8 字節(jié)絕大多數(shù)業(yè)務(wù)默認(rèn)選擇C 中浮點(diǎn)字面量默認(rèn)是 double??工程坑點(diǎn)浮點(diǎn)數(shù)不要直接用判斷相等存在精度丟失。 正確做法判斷兩個浮點(diǎn)數(shù)差值是否小于一個極小閾值例如fabs(a?b) 1e?9。3. 字符類型char1 字節(jié)存儲單個字符使用單引號包裹例如char c X;本質(zhì)是小整數(shù)可以存 ASCII 編碼值。補(bǔ)充支持轉(zhuǎn)義字符常見如換行\(zhòng)n、反斜杠\新手書寫路徑、換行文本時高頻遇到。4. 布爾類型bool布爾類型只有兩個取值true/false底層存儲 1 字節(jié)true等價非 0false等價 0。補(bǔ)充變量初始化好習(xí)慣定義變量盡量顯式初始化不要使用未初始化變量內(nèi)存是隨機(jī)臟數(shù)據(jù)。二、字面量、變量、常量概念區(qū)分字面量寫死在代碼中的直接值10、3.14、M本身不能修改變量內(nèi)存空間可以讀寫修改int val 20; val 30;常量內(nèi)存空間初始化賦值后運(yùn)行期間禁止修改。C 有兩套實(shí)現(xiàn)const、#define三、const 修飾常量onst int BUFFER_SIZE 4096;const修飾的變量定義時必須初始化之后不能修改嘗試修改直接編譯報錯。屬于編譯器處理是真正的類型安全常量保留完整類型信息。作用域遵循普通變量作用域局部 const 只在函數(shù)內(nèi)部生效全局 const 有文件作用域。小提示C11 以后推薦優(yōu)先使用 const是工程代碼主流寫法。四、#define 定義宏常量define MAX_USER 500#define是預(yù)處理指令預(yù)處理階段做簡單文本字符串替換沒有類型檢查。預(yù)處理階段代碼所有MAX_USER純文本替換成500編譯階段已經(jīng)不存在這個符號。典型宏陷阱五、工程取舍const VS #define方案優(yōu)點(diǎn)缺點(diǎn)適用場景const帶類型檢查、作用域可控、調(diào)試器可以看見符號需要遵循變量作用域絕大多數(shù)業(yè)務(wù)代碼優(yōu)先選 const#define預(yù)處理直接替換無內(nèi)存開銷無類型、無作用域、容易出現(xiàn)文本替換 BUG調(diào)試看不到宏符號底層宏開關(guān)、簡單編譯期配置業(yè)務(wù)層盡量少用工程結(jié)論業(yè)務(wù)開發(fā)盡量使用const不要用#define去定義普通數(shù)值常量。六、新手高頻踩坑匯總int 存儲過大數(shù)值發(fā)生整數(shù)溢出不會崩潰產(chǎn)生錯誤結(jié)果屬于隱蔽 BUG大數(shù)直接上long long。給 unsigned 變量賦值負(fù)數(shù)靜默轉(zhuǎn)換超大正數(shù)邏輯異常例如unsigned int x -1得到 4294967295。const 常量忘記初始化直接編譯報錯。#define 宏常量表達(dá)式缺少括號替換后運(yùn)算優(yōu)先級錯亂。浮點(diǎn)數(shù)使用直接對比兩個小數(shù)精度丟失判斷失效改用差值小于極小值如 1e?9做判斷。char 使用雙引號賦值混淆字符與字符串編譯報錯同時留意\n、\\這類轉(zhuǎn)義字符書寫。本期思考題const int a 10;嘗試寫a 20;會在編譯期還是運(yùn)行時報錯為什么業(yè)務(wù)代碼不推薦大量使用 #define 定義數(shù)值常量int 和 long long 同樣存整數(shù)什么時候必須選 long long下期預(yù)告下一節(jié)cin/cout控制臺輸入輸出與std命名空間規(guī)范