開發過程中的經常需要使用一些全域性的常量,便於方法之間的引數傳遞和型別確定等,經常使用到的有巨集定義,const常量以及列舉等,我們經常使用巨集定義來進行全域性常量的定義,但是是不是所有的全域性常量巨集定義都是最好的選擇呢?
巨集定義是我們最經常使用的全域性常量定義方法,使用非常便捷,在使用過程中需要注意以下事項:
1.巨集定義是預編譯處理,在程式開始編譯之前就已經完成;
2.巨集定義只是進行字元替換,並沒有優先順序限制,比如
#define add(x,y)x + y
在使用時如果使用了add(3,4)*add(3,4),巨集定義替換之後的結果是3+4*3+4=19,而不是(3+4)*(3+4) =49,一定要注意!!!
3.巨集定義不做型別的語法檢查,巨集定義中巨集的所有引數都是沒有型別的,可能會存在重複定義的問題,如果重複定義了相同名稱的巨集,程式只是會給出警告,而不會影響編譯,所以如果你定義了同名稱兩個巨集,而替換方式不一樣的話,是很難發現的。
4.巨集定義不是變數定義,所以並不分配記憶體;
5.巨集定義只是字串替換,結尾不需要使用使用分號結束。
const是變數修飾符號,在定義全域性變數的時候,應該優先考慮static加上const來替換巨集定義常量,原因有以下幾點:
1.當專案比較大的時候,過多的巨集定義會使專案的編譯變得緩慢;
2.const修飾變數在編譯期間會進行語法檢查,可以防止意外的型別錯誤,以及重複定義,可以使定義更加安全;
3.const修飾變數時,該變數不允許改變,可以防止常量被意外修改;
4.在需要使用的地方,只需要使用extern關鍵字擴大變數的作用域,使得變數的訪問更加靈活。
對於const的使用,需要注意以下事項:
1.const修飾普通變數,表示該變數為常量,使用過程中不允許修改;
2.const修飾指標類變數;含有位址的變數時,以*分為左右兩部分,左側部分含有const修飾符號時,該位址內容不能改修;右側部分還有const修飾時,該變數位址不能改變,如果兩側都有const修飾,則記憶體位址和位址內容都不可變;
3.const可以修飾形參,被修飾的引數在方法內部不能被修改;
4.被const修飾的變數的作用域,可以通過extern進行擴充套件,不需要進行初始化和分配空間,只是告訴編譯起該變數會在其他地方進行定義。
對於互斥(不能同時具有兩種狀態)表示的多種整型變數,一般推薦使用ns_enum來表示,使用很簡潔,也很方便。比如文字在豎直方向的對齊狀態
typedef
ns_enum(nsinteger, uicontrolcontentverticalalignment) ;
這種表示的優點是可以將多種實用普通整型數字不易區分的狀態,用易於區分的字串表示,見名知意,不易出錯,方便表示。但是這種表示方法的不足之處就是各種狀態之間不能並存,但是有些時候我們需要使用多種狀態同時存在,比如選擇了乙個通訊錄裡的聯絡人需要獲取的資訊型別
typedef
ns_options(nsuinteger, apcontactfield) ;
如果你需要同時選定姓名和****,只需要定義 _enums = apcontactfieldfirstname|apcontactfieldlastname|
apcontactfieldphones就可以了,
那麼問題來了,對於這種可以同時選擇多個屬性的列舉型別,如何確定某個列舉值(比如apcontactfieldfirstname)是不是包含在選定列舉(比如_enums)中呢?
只需要將(apcontactfieldfirstname)&(_enums)運算,如果其值為真,則包含,否則為假。
iOS中關於巨集定義與常量的使用
現在在做的這個產品,由於需求不斷的新增,工程越來越大,編譯速度是越來越慢。之前就看過帖子 使用巨集定義過多的話,隨著工程越來越大,編譯速度會越來越慢。static cgfloat const klogoimagewidth 100 logo寬度 static cgfloat const klogoi...
巨集定義與列舉
巨集定義是在預編譯時直接進行替換。而列舉值要在編譯時才能確定其值。所以任何在巨集定義中引用列舉值的操作都是錯誤的。在下面的 中,編譯輸出為 test1 1,num1 111 test2 2,num2 222 include include define aaa 1 define bbb 2 defi...
常量與列舉型別
常量的使用需要注意以下幾點 1 常量需要在型別關鍵字之前加上 const 表示是關鍵字。const 本身就是常量的意思 2 常量中的所有的字母全部都是大寫,而且定義的名字必須要有一定的意義,做到 見名知意 如 pi 3 常量在定義時,就必須初始化 即,給出初始值 列舉型別的定義需要注意的幾點要求。1...