如何正確使用const(常量),define(宏)

前言

在開發中,也許咱們會常常使用到宏定義,或者用const修飾一些數據類型,常常有開發者不知道怎麼正確使用,致使項目中亂用宏定義與const修飾符。本篇主要介紹在開發中怎麼正確使用constdefine(宏定義)函數

當咱們想定義全局共用的一些數據時,好比通知名字,動畫時長等等,咱們能夠用常量變量測試

  • 宏:優化

    // 注意後面不須要帶符號
        #define ScottDidLoginSuccess @"登錄成功"
  • 變量:動畫

    // 注意後面必定要帶符號
        NSString *scottDidLoginSuccess = @"登錄成功";
  • 常量:調試

    // 四種寫法
        static const NSString *scottDidLoginSuccess = @"登錄成功";
        const NSString *scottDidLoginSuccess = @"登錄成功";
        NSString const *scottDidLoginSuccess = @"登錄成功";
        NSString *const scottDidLoginSuccess = @"登錄成功";

那麼問題來了,咱們到底該如何選擇呢?
讓我來先將一下我對它們之間的理解吧:code

  • 宏:只是在預處理階段進行文本替換,沒有類型,不作任何類型檢查,編譯器能夠對相同的字符串進行優化,只保存一份到數據段。甚至有相同後綴的字符串也能夠優化,你可使用GCC編譯測試,Hello worldworld兩個字符串,只存儲前面一個。取的時候只須要給前面和中間的地址,若是是整型、浮點型會有多分拷貝,但這些數寫在指令中,佔的只是代碼片斷並且,大量使用宏會致使二進制文件變大。
  • 變量:共享一塊內存空間,就算項目中N處用到,也不會分配N塊內存空間,能夠被修改,在編譯階段作類型檢查。
  • 常量:共享一塊內存空間,就算項目中N處用到,也不會分配N塊內存空間,能夠根據const修飾的位置設定可以修改,在編譯階段作類型檢查。

常量區分

  • 全局常量:無論你定義在任何文件夾,外部都能訪問內存

    const NSString *scottDidLoginSuccess = @"登錄成功";
  • 局部常量:用static修飾後,不能供外界訪問開發

    static const NSString *scottDidLoginSuccess = @"登錄成功";

const修飾位置不一樣,表明什麼

// 1.
    const NSString *scottDidLoginSuccess = @"登錄成功";
    // 2.
    NSString const *scottDidLoginSuccess = @"登錄成功";
    // 3.
    NSString * const scottDidLoginSuccess = @"登錄成功";

咋一看,WTF,這不都張同樣嘛,其實不同,下面解釋一下各表明什麼字符串

  1. *scottDidLoginSuccess不能被修改,scottDidLoginSuccess能被修改
  2. *scottDidLoginSuccess不能被修改,scottDidLoginSuccess能被修改,也就是和第一種狀況是同樣的
  3. scottDidLoginSuccess不能被修改,*scottDidLoginSuccess能被修改。

結論:const右邊的總不能被修改編譯器

因此咱們通常定義一個常量又不想被修改,應該這樣定義:
NSString *const scottDidLoginSuccess = @"登錄成功";

二者之間的區別

  • define在預處理階段進行替換,const常量在編譯階段使用;
  • define不作類型檢查,只進行替換,const常量有數據類型,會執行類型檢查;
  • define不能調試,const常量能夠調試;
  • define定義的常量在替換後運行過程當中,會不斷佔用內存,而const定義的常量存儲在數據段,只有一份拷貝,效率更高;
  • define能夠定義函數,const不能夠。
相關文章
相關標籤/搜索