1. 程式人生 > >如何正確使用const(常量),define(宏)

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

success AS 問題 指令 fin 函數 之間 登陸 共享

前言

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

當我們想定義全局共用的一些數據時,比如通知名字,動畫時長等等,我們可以用常量變量

  • 宏:

        // 註意後面不需要帶符號
        #define ScottDidLoginSuccess @"登陸成功"
  • 變量:

        // 註意後面一定要帶符號
        NSString *scottDidLoginSuccess = @"登陸成功";
  • 常量:

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

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

  • 宏:只是在預處理階段進行文本替換,沒有類型,不做任何類型檢查,編譯器可以對相同的字符串進行優化,只保存一份到數據段。甚至有相同後綴的字符串也可以優化,你可以使用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不可以。

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