2015-02-07 65 views
1

我很好奇C#中的foreach循環如何遍歷多維數組。在下面的代碼中,第二個嵌套的for循環最初是一個foreach,它將給出放置在循環中的音高的不正確位置。我知道這很難直觀,但它基本上是這樣的:把音調放到一個多維數組中(這裏numVoices是2,exLength是10),這樣你就可以得到一個2×10的音高數組; MIDI輸出設備會同時播放這些行間距中的每一行。當我使用foreach將球場名稱放入一個字符串中,以便我可以顯示球場內什麼位置的球場時,foreach會以「錯誤」的順序顯示它們(即[0,3]在間距網格中不是打印在字符串中的)。使用嵌套for,此問題消失。我試圖用一個較小的int s列表(下面的代碼)重新創建這個例子,但這次給出了「正確」的答案。爲什麼?`foreach`如何遍歷2D數組?

  //put pitches into grid 
      //numVoices = 2, exLength = 10 (10 notes long, 2 voices) 
      for (int i = 0; i < numVoices; i++) 
      { 
       for(int j = 0; j < exLength; j++) 
       { 
        //here we generate random pitches in different octaves 
        //depending on the voice (voice 2 is in octave 
        //below voice 1, etc) 
        randnum = (random.Next(100 - (i * 13), 112 - (i * 13)));       

        melodyGrid[j, i] = (Pitch)randnum; 

       } 
      } 

      for (int i = 0; i < numVoices; i++) 
      { 
       for (int j = 0; j < exLength; j++) 
       { 
            //this down here makes it more readable for 
            //humans 
            //e.g. "FSharp5" becomes "F#5" 

        noteNames += String.Format("{0, -6}", melodyGrid[j,i].ToString().Replace("Sharp", "#").Replace("Flat", "b")); 

       } 
       noteNames += "\r\n"; //lower voices are just separated by newlines 
      } 
      Console.WriteLine(noteNames); 

下面的代碼工作 「正常」,但是:

int[,] nums = { {1, 2, 3}, 
          {4, 5, 6}, 
          {7, 8 ,9} }; 
      foreach (int i in nums) 
      { 
       Console.Write("{0} ", i); 
      } 

是否有可能我只是做一個語義錯誤?或者foreach循環以不同的方式遍歷數組?

回答

4

我很好奇C#中的foreach循環如何遍歷多維數組。

像往常這樣的問題,最終的權威是C#語言規範。在這種情況下,第8.8.4節:

foreach遍歷數組元素的順序如下:對於一維數組,元素以遞增的索引順序遍歷,從索引0開始並結束索引號爲Length – 1。對於多維數組,遍歷元素使得最右邊的維度的索引首先增加,然後是下一個左邊的維度,以此類推至左邊。

現在,比較,與你是如何與你的for語句迭代:

for (int i = 0; i < numVoices; i++) 
{ 
    for(int j = 0; j < exLength; j++) 
    { 
     ... 
     melodyGrid[j, i] = (Pitch)randnum; 

換句話說,你第一次遞增最左邊維...所以,是的,這將給出與foreach不同的結果。如果您想使用foreach但獲得相同的迭代順序,則需要切換聲音和長度的索引。或者,如果您想保持索引的相同順序,只需使用for循環並對此感到滿意。

+0

太棒了,謝謝! – aaaaaaaaaaa 2015-02-08 02:03:44