aaa*_*aaa 1 c# arrays foreach for-loop multidimensional-array
我很好奇 C# 中的循环如何foreach
迭代多维数组。在下面的代码中,第二个嵌套for
循环最初是 a foreach
,这会给出循环中放置的音高的不正确位置。我知道很难凭直觉了解它的作用,但它基本上是这样的:将音调放入多维数组中(此处,numVoices 为 2,exLength 为 10),这样您将拥有一个 2x10 的音调数组;然后,MIDI 输出设备会同时播放这些音高行中的每一行。当我使用 aforeach
将音高名称放入字符串中以便我可以显示网格内哪个位置的音高时,会foreach
以“错误”顺序显示它们(即,[0,3]音高网格不是字符串中打印的内容)。使用嵌套for
,这个问题就消失了。我尝试用 s 的二维列表的较小示例int
(下面的代码)重新创建它,但这次它给出了“正确”的答案。为什么?
//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);
Run Code Online (Sandbox Code Playgroud)
但是,以下代码可以“正确”工作:
int[,] nums = { {1, 2, 3},
{4, 5, 6},
{7, 8 ,9} };
foreach (int i in nums)
{
Console.Write("{0} ", i);
}
Run Code Online (Sandbox Code Playgroud)
我有可能只是犯了一个语义错误吗?或者foreach
循环是否以不同的方式迭代数组?
\n\n\n我很好奇 C# 中的 foreach 循环如何迭代多维数组。
\n
与往常一样,对于此类问题,最终权威是 C# 语言规范。在这种情况下,第 8.8.4 节:
\n\n\n\n\nforeach 遍历数组元素的顺序如下: 对于一维数组,按递增索引顺序遍历元素,从索引 0 开始,以索引 结束
\nLength \xe2\x80\x93 1
。对于多维数组,遍历元素时首先增加最右边维度的索引,然后是左下一个维度,依此类推。
现在,将其与您迭代for
语句的方式进行比较:
for (int i = 0; i < numVoices; i++ )\n{\n for(int j = 0; j < exLength; j++)\n {\n ...\n melodyGrid[j, i] = (Pitch)randnum;\n
Run Code Online (Sandbox Code Playgroud)\n\n换句话说,您首先增加最左边的维度...所以是的,这将给出与foreach
. 如果您想使用foreach
但获得相同的迭代顺序,则需要切换语音和长度的索引。或者,如果您想保持相同的索引顺序,只需使用循环for
即可。