我有一个小程序可以模拟自动点唱机。 我有一个所有歌曲的课程,以及一个包含Song课程的所有专辑的课程。
在此功能中,我将打印出Album矢量中的所有歌曲,并使用迭代器为每首歌曲编号。 1.2.3.4.etc
当我在第二个for循环中声明“int i”时,然后在每个专辑之后,int“i”将再次变为0。但是当我在所有For循环之前声明它时,我只会打印第一张专辑。
怎么回事?
void Jukebox::createList() {
int i = 0;
for (auto idx : albvec)
{
// Write out the songs
for (i; i < idx.getNrSongs(); i++)
{
cout << i+1 << " " << idx.getSongvec()[i].getArtist() << " - ";
cout << idx.getSongvec()[i].getTitle() << " ";
Time t = idx.getSongvec()[i].getDuration();
printTime(t);
cout << endl;
}
}
}
答案 0 :(得分:4)
当我宣布&#34; int i&#34;在第二个for循环中,然后在每个专辑之后的那个int&#34; i&#34;将再次变为0。但是当我在所有For循环之前声明它时,我只会打印第一张专辑。
怎么回事?
当为第二张专辑执行内部循环时,值i
不会重置为零。
更改
for (i; i < idx.getNrSongs(); i++)
到
for (i = 0; i < idx.getNrSongs(); i++)
良好的编码实践之一是保持变量范围尽可能小。因此,您的用例最好使用:
for (int i = 0; i < idx.getNrSongs(); i++) { ... }
答案 1 :(得分:3)
您的for
循环:for (i; i < idx.getNrSongs(); i++)
应该是:for (i = 0; i < idx.getNrSongs(); i++)
。基本上for
循环由初始化,继续条件和递增部分组成,初始化部分不会重置i
的值。基本上你会记住i
的值,所以当完成第一张专辑时,处理下一张专辑时不会达到继续条件,因此你不会进入下一张专辑内循环,除非该专辑有更多的歌曲比以前的。
答案 2 :(得分:1)
因为i
与第一个for循环具有相同的范围,所以它不会在第二个for循环开始时重新初始化。这意味着
在第一个for循环结束后,您最终i
大于idx.getNrSongs()
并且不再满足任何其他条件。
int i = 0;
for (auto idx : albvec)
{
// Write out the songs
for (i; i < idx.getNrSongs(); i++)
{
cout << i+1 << " " << idx.getSongvec()[i].getArtist() << " - ";
cout << idx.getSongvec()[i].getTitle() << " ";
Time t = idx.getSongvec()[i].getDuration();
printTime(t);
cout << endl;
}
// at this point, i is now greater than idx.getNrSongs().
// since the scope of i is not local to the for loop, it's
// value will be kept for the next for loop iteration! Meaning
// if i ends at 5 for example on the first loop, it will start
// with 5 on the second loop
}
答案 3 :(得分:1)
如果您希望所有专辑中的歌曲编号唯一,那么您需要创建一个额外的变量songNum来跟踪歌曲编号。将此初始化为两个循环的零。然后对内循环使用(对于int i = 0; i&lt; ....)。将您的打印更改为使用songNum而不是i,然后记住增加songNum。