宏(define):
#define Str @"字符串"
只是在預處理器里進行文本替換,沒有類型,不做任何類型檢查,編譯器可以對相同的字符串進行優(yōu)化。只保存一份到 .rodata 段。甚至有相同后綴的字符串也可以優(yōu)化,你可以用GCC 編譯測試,"Hello world" 與 "world" 兩個字符串,只存儲前面一個。取的時候只需要給前面和中間的地址,如果是整形、浮點型會有多份拷貝,但這些數(shù)寫在指令中。占的只是代碼段而已,大量用宏會導致二進制文件變大
常量(const):
共享一塊內(nèi)存空間,就算項目中N處用到,也不會分配N塊內(nèi)存空間,可以根據(jù)const修飾的位置設(shè)定能否修改,在編譯階段會執(zhí)行類型檢查
1)const NSString *str = @"字符串";
//*str 不能被修改? str能被修改
2)NSString const *str = @"字符串";
//*str 不能被修改? str能被修改
3)NSString * const str = @"字符串";
//*str 能被修改? str不能被修改
4)NSString const * const str = @"字符串";
//*str 不能被修改? str不能被修改
5)const NSString * const str = @"字符串";
//*str 不能被修改? str不能被修改
結(jié)論:const右邊的總不能被修改
比較:
1) 編譯器處理方式不同
define宏是在預處理階段展開。
const常量是編譯運行階段使用。
2) 類型和安全檢查不同
define宏沒有類型,不做任何類型檢查,僅僅是展開。
const常量有具體的類型,在編譯階段會執(zhí)行類型檢查。
3) 存儲方式不同
define宏僅僅是展開,有多少地方使用,就展開多少次,不會分配內(nèi)存。(宏定義不分配內(nèi)存,變量定義分配內(nèi)存。)
const常量會在內(nèi)存中分配(可以是堆中也可以是棧中)。
4)內(nèi)存分配大小不同
define定義的常量在內(nèi)存中有若干個拷貝。
const定義常量從匯編的角度來看,只是給出了對應的內(nèi)存地址,所以,const定義的常量在程序運行過程中只有一份拷貝(因為是全局的只讀變量,存在靜態(tài)區(qū))。
5) 效率不同。
?編譯器通常不為普通const常量分配存儲空間,而是將它們保存在符號表中,這使得它成為一個編譯期間的常量,沒有了存儲與讀內(nèi)存的操作,使得它的效率也很高。
6)作用不同
宏不只能定義常量,還能定義函數(shù)?