我认为计算机科学学习中最重要的概念之一是了解数组索引的工作原理。你应该花一些时间用简单的例子清楚地向学生解释这个概念。自 LISP 以来,几乎所有编程语言都以 Zero-based numbering 开头。 Python 和 C++ 没有什么不同。在 Python 中,可以使用简单的lists 作为示例来说明概念。
#a simple list
In [15]: list1 = [1,2,3,4,5,6,7,8,9,10,11]
In [23]: len(list1) #number of items in the list
Out[23]: 11
In [26]: list1[0] #the first item in the list
Out[26]: 1
In [25]: print("list1 starts at index {}. The number at this index is {}.".format(list1.index(1), list1[0]))
list1 starts at index 0. The number at this index is 1.
In [37]: list1[10] #the last item in the list
Out[37]: 11
In [19]: print("list1 ends at index {}. The number at this index is {}.".format(len(list1)-1, list1[-1]))
list1 ends at index 10. The number at this index is 11.
如您所见,“数字”值比“索引”值早1。如果列表 list1 以 0 开头并以 11 结尾,那么索引值和“数字”值将相同,但列表中的项目数将增加 1,这是因为我们包含了 0。暂时保持这个想法,因为我们需要这个:
In [29]: list2 = [0,1,2,3,4,5,6,7,8,9,10,11]
In [31]: len(list2) #total number of items in list
Out[31]: 12
In [32]: list2[0]
Out[32]: 0
In [35]: list2[11]
Out[35]: 11
请记住,根据文档,range() 的语法是:range(start, end, step)。我们将忽略此讨论的步骤。
所以,现在如果我想使用range() 生成与list2 类似的列表,我可以使用上述信息来形成 range() 的通用语法:
Syntax: range(start, len(list2)+start), where start is the first item in the range,
list2 is a list and len(list2) is its size and the end is len(list2) + start
要将其放入列表中,我只需将上述内容作为参数传递给list() 函数。深入了解此功能的本质并不重要,仅用于说明。因此,我们得到:
In [39]: list3 = list(range(0,len(list2)+0))
In [40]: list3
Out[40]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
In [41]: list2 == list3 #both lists are equivalent
Out[41]: True
In [42]: len(list3)
Out[42]: 12 #same number of items as list2
In [46]: for i in range(0,len(list3)+0): #can replace list3 with list2 to get same results
...: print(i, end=' ')
...:
0 1 2 3 4 5 6 7 8 9 10 11 #Output
for 循环按索引位置进行迭代。因此,i 从第 0 项的索引位置 0(范围开始)开始,一直到第 11 项的索引位置 11(范围结束 = 11 + 0)。
我们还可以验证list1 的上述语法,其中 start 为 1,长度为 11。
In [6]: list(range(1,len(list1)+1))
Out[6]: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11] #same as list1 above
In [15]: for i in range(1,len(list1)+1):
...: print(i, end=' ')
...:
1 2 3 4 5 6 7 8 9 10 11
同样,for 循环像往常一样从索引位置 0 开始,其中包含项目 1(范围开始),并在索引位置 10 结束,其中包含项目 11(范围结束 = 11 + 1)。
现在,让我们看看这个概念如何也适用于 C++。我们使用相同的list2,它有 12 个项目,即len(list2) = 12。同样,如果学生对数组不太熟悉,那么深入了解以下示例中的所有细节并不重要。这仅用于说明目的:
#include <iostream>
using namespace std;
int main()
{
int list2[12] = {0,1,2,3,4,5,6,7,8,9,10,11};
std::cout << "Length of array list2 = " << (sizeof(list2)/sizeof(*list2)) << std::endl;
for(int i=0;i<(sizeof(list2)/sizeof(*list2));i++)
{
cout<<i<<' ';
}
return 0;
}
//Output:
Length of array list2 = 12
0 1 2 3 4 5 6 7 8 9 10 11 #Output
注意i<(sizeof(list2)/sizeof(*list2)) 确保从数组的上限检索最后一项,即索引=12-1=11 的第 11 项。这正是range() 函数的作用。如果我执行i<=(sizeof(list2)/sizeof(*list2)),那也会在输出中打印 12,这不是list2 中的项目,并且会超出数组的上限。在 Python 中,range() 函数对数组边界更加明确。因此,如果我覆盖上面的 range() 语法并允许 for 循环通过将 end 递增 1 从 0 迭代到 list2 之外的项目,我可以显式打印该项目:
In [13]: for i in range(0,len(list2)+1):
...: if i>=len(list2):
...: print("\nI am outside of list2: {}".format(i))
...: else:
...: print(i, end=' ')
...:
0 1 2 3 4 5 6 7 8 9 10 11
I am outside of list2: 12
我们从这次讨论中了解到,将 for 循环迭代理解为基于索引的操作很重要,range(start,end) 是 Python 内置函数,它仅在开始和结束之间组合值 范围,包括起始值,不包括结束值。考虑遍历的值的总数,包括 start(len(total) + start) 作为范围的 end 处的项目。 for 循环的实现与此无关,只考虑 Python 和 C++ 中的索引位置。