這裏C編程指南和編碼標準說,我們必須從程序避免幻數,並使用宏幻數爲什麼我們要避免編程中的Magic Numbers或Constants並使用宏?
在宏會花費更多的時間來評估作爲比較常量這樣的表現是神奇的號碼或更多更好常量。
爲例
for(i=0;i<255;i++)
{
}
我們用這個
#define MAX 255
for(i=0;i<MAX;i++)
{
}
第二個是需要更多的時間比較第一個,爲什麼我們更喜歡第二個按照編碼標準。
這裏C編程指南和編碼標準說,我們必須從程序避免幻數,並使用宏幻數爲什麼我們要避免編程中的Magic Numbers或Constants並使用宏?
在宏會花費更多的時間來評估作爲比較常量這樣的表現是神奇的號碼或更多更好常量。
爲例
for(i=0;i<255;i++)
{
}
我們用這個
#define MAX 255
for(i=0;i<MAX;i++)
{
}
第二個是需要更多的時間比較第一個,爲什麼我們更喜歡第二個按照編碼標準。
使用宏常量不需要更多時間。 #define
是preprocessor指令,所以在二進制代碼中,這兩段代碼會編譯成相同的東西!
但是,由於maintainability的原因,我們避免使用'幻數',假設您有許多相同大小的循環和數組,如果將來這個大小發生變化,您需要搜索代碼並將其更改,[只有它!],而如果使用預處理器命令,則只需更改它[預處理器命令]。
這兩段代碼將被編譯爲相同的東西。當預處理器運行時,MAX
的實例被替換爲255,因此編譯器正在使用完全相同的代碼。
使用#define
或恆定的好處是,如果該值在多個地方使用,且必須chaned出於某種原因,是微不足道的改變#define
,而不是找到正在使用的值的所有地方和改變他們。
第二個是優選的,因爲讀出循環時給出的含義。對於有人進來並維護你在第一個例子中寫的代碼,顯而易見的問題是「爲什麼255」?這是什麼意思,如果我修改它會發生什麼?給這個值起個名字就更清楚了,並且定義它。如果在整個程序中使用相同的號碼,只需要在一個地方進行修改。
至於這樣做的成本,它很小。在編譯時,MAX的所有實例都將被替換爲255.在運行時,沒有成本。
這是關於主流,而不是性能。任何時候你爲同一目的重複兩次相同的數字,它應該放在變量,宏或常量中。閱讀DRY;代碼或值的重複大大增加了未來錯誤的可能性。
我相信宏在編譯時被擴展,而不是運行時,所以根本沒有性能損失。即使有一個常量,也沒有可測量的差異 - 我相信不到一個週期。
還查找過早優化。
編譯C程序時,程序首先由C預處理器處理。它處理程序中的所有#foo
東西,並替換宏。當編譯器看到代碼時,您的宏已被替換爲值。
因此,如果您將第二個代碼片段提供給編譯器,那麼實際的 C編譯器將會看到與第一個代碼片段中完全相同的內容。這意味着使用宏而不是而不是會減慢您的程序。
有關使用宏(或常量)的想法是讓您的數字具有可能對人類有意義的名稱。
考慮你的程序支持三輛自行車(或其他,無所謂)。你需要在很多地方寫3
(比如你在for
循環中寫了255)。但一個月後,當你看到它時,你可能還記得一個3的更多含義。如果您改爲:
#define MAX_BICYCLES 3
然後在各處使用MAX_BICYCLES
意圖變得更清楚。更好的是,一旦你的應用程序支持5輛自行車,它可能就像改變一個宏一樣簡單。您不必記住在哪個地方將3
更改爲5
。
如果發生了數字變化或數字顯然是錯誤的,您會如何知道?
而不是幻數使用一個真正的名字,意味着什麼。
您可以使用#define或常量或枚舉作爲名稱。
哪一個是設計選擇。
例如:
#define PRESIDENT_WENT_CRAZY (22)
const int WE_GOOFED= 19;
enum {
THEY_DIDNT_PAY= 16
};
if (PRESIDENT_WENT_CRAZY == foo) { start_thermo_nuclear_war(); }
else if (WE_GOOFED == foo) { refund_lotso_money(); }
else if (THEY_DIDNT_PAY == foo) { infinite_loop(); }
else { happy_days_i_know_why_im_here(); }
現在是不是更好?
const和enum選項是可取的,因爲在調試調試器時有足夠的信息來顯示值和標籤。
「在宏中,它需要更多的時間來評估與常量比較」不,它不會。除非你講的是編譯時間,可能會稍微長一些。 –
1:幻數不傳達作者的意思,2:幻數,重複時,需要更多時間更改 – Ptival
http://en.wikipedia.org/wiki/Magic_number_(programming)#Unnamed_numerical_constants –