2010-01-18 102 views
7

我是一個相當新的程序員,我很抱歉如果這些信息很容易找到,我還沒有找到它。數組中的魔術數字? - C++

我的問題是:

是被認爲是神奇數字,當你使用文字號碼訪問數組的特定元素?

例如:

arrayOfNumbers[6] // Is six a magic number in this case? 

我問這個問題,因爲我的一個教授堅持認爲,程序中的所有文字數字是幻數。對我來說,使用實數來訪問數組的元素將會很好,而不是使用每個元素的命名常量。

謝謝!

+1

'#define ONE 1' ...'i + = ONE;' – 2010-01-18 21:46:56

+2

爲了避免這種情況,上帝給了我i ++:P – Leo 2010-01-18 21:48:07

+1

是的。 6是一個幻數。在代碼中避免幻數總是比較好的,例如:#define PI 3.1416',如果pi的值發生變化,比在整個代碼中使用3.1416更好。 – 2010-01-18 21:48:33

回答

22

這真的取決於上下文。如果你有這樣的代碼:

arr[0] = "Long"; 
arr[1] = "sentence"; 
arr[2] = "as"; 
arr[3] = "array."; 

...然後0..3不被視爲幻數。但是,如果您有:

int doStuff() 
{ 
    return my_global_array[6]; 
} 

...然後6確切地說是一個幻數。

+0

Ahh,O.K.這就說得通了。 – Alex 2010-01-18 22:11:58

5

你應該問自己,你爲什麼要訪問這個特定的位置。在這種情況下,我假設如果你在做arrayOfNumbers[6]第六位有一些特殊的含義。如果你認爲這是什麼意思,你可能會意識到這是一個隱藏的神奇數字。

0

如果您需要訪問數組中的特定元素,您可能會犯錯。

你應該幾乎總是迭代整個數組。

6

這很神奇。

我的意思是,爲什麼在訪問第6個元素?什麼是應該應用於這個數字的語義?就目前而言,我們所知的只是「第六(零基)」號碼。如果我們知道arrayOfNumbers的聲明,我們會進一步知道它的類型(例如,intdouble)。

但是,如果你說:

arrayOfNumbers[kDistanceToSaturn]; 

...現在有更多的含義,有人閱讀的代碼。

一般來說,迭代一個數組,對每個元素執行一些操作,因爲不知道數組有多長,你不能以硬編碼的方式訪問它。

但是,有時數組元素具有特定的含義,例如在圖形編程中。有時數組總是相同的大小,因爲數據需要它(例如某些變換矩陣)。在這些情況下,按數字訪問特定元素可能會也可能不會:領域專家會知道您在做什麼,但通才可能不會。賦予魔術索引號一個名稱可以讓那些必須維護代碼的人更加明顯,並且可以幫助您防止意外鍵入錯誤的名稱。

在我上面的例子中,我假設你的陣列擁有從太陽到行星的距離。太陽將是第零個元素,因此arrayOfNumbers [kDistanceToSun] = 0.然後,當你增加時,每個元素包含到下一個最遠行星的距離:水銀,金星等。這比只輸入數字你想要的星球。在這種情況下,陣列的大小是固定的,因爲有一定數量的行星(除了整個冥王星崩潰之外)。

另一個問題是「arrayOfNumbers」沒有告訴我們有關數組的內容。我們已經知道它的一系列數字,因爲我們看到了某處的聲明,在那裏您說int arrayOfNumers[12345];或您聲明瞭它。相反,如下所示:

int distanceToPlanetsFromSol[kNumberOfPlanets]; 

...給了我們一個關於數據實際是什麼以及它的語義是什麼的更好的概念。你作爲程序員的目標之一應該是編寫以這種方式自我記錄的代碼。

,然後我們可以在其他地方認爲,如果kNumberOfPlanets應該是8或9 :)

+0

那麼這取決於你是否計算了兩次火星。 – 2010-01-19 01:59:15

0

這只是不是一個神奇的數字,如果你的程序是做涉及老六特別很特別的東西。你能提供一些背景嗎?

1

您必須爲有意義的答案提供更多上下文。並非所有的文字數字都是魔法,但很多都是。在這樣的情況下,根本沒有辦法可以肯定地說,儘管大多數情況下,我可以用一個明確的數組索引>> 1來考慮可能是魔術。

0

這是教授的問題,他們往往太學術。從理論上講,他是正確的,但通常情況下,當數字嵌入在數據流中時,通常會在更嚴格的上下文中使用幻數,從而允許您檢測流的某些屬性(例如,文件類型的簽名頭實例)。 另請參閱this Wikipedia entry

+0

然後你應該使用命名常量,而不是幻數。 – 2010-01-18 21:48:28

+0

該死的寫下你剛纔寫的東西。 +1。 – 2010-01-18 21:49:27

1

不是全部程序中的文字確實符合「神奇數字」的要求 - 但這似乎確實如此。 6不讓我們知道爲什麼你要訪問數組中的特定元素。

不是是一個神奇數字,即使在第一次檢查(或至少是最小的檢查)時,它的含義也需要很清楚。舉個例子來說,很多代碼會做這樣的事情:&x[0]。在這種情況下,通常非常清楚的是,'0'的確意味着「數組的開始」。

0

通常不是所有軟件中的常量值都稱爲幻數。 一個java類文件總是以十六進制值0xcafebabe開頭,一個windows .exe 文件帶有MZ 0x4d,0x5a,這可以讓你快速(但不是確定地)識別 二進制文件的內容。

2

另一種方式來看待它:

如果以後有機會的一些程序需要訪問7元而不是6?你會或維護者知道嗎?例如,如果如果第6項是在CA樹木計數這將是一件好事,把

#define CA_STATE_ENTRY 6 

那麼,如果現在表被重新排序有人能看到,他們需要把這個改爲9(說) 。順便說一句我並不是說這是按狀態維護樹數的最佳方法 - 它可能不是。

同樣,如果以後人們想改變計劃,以應對在俄勒岡州的樹木,然後他們知道,以取代

trees[CA_STATE_ENTRY] 

trees[OR_STATE_ENTRY] 

的一點是

trees[6] 

不是自我記錄

當然,對於C++而言,它應該是enum而不是#define

0

在符合MISRA的系統中,除0和1之外的所有值均被視爲幻數。我的意見一直是如果恆定的價值是顯而易見的或者可能不會改變,那麼將其作爲一個數字。如果有疑問可以創建一個獨特的常量,因爲長期維護會更容易。