我注意到关于C#/ Java的一些东西(目前对我而言)与数组大小声明和数组大小的默认第一索引存在不一致的问题。
使用数组时,假设您要创建一个新的整数数组大小3
,它将如下所示:
int[] newArray = new int[3] {1, 2, 3};
完全找到并且可读......对吧?
编程语言的标准似乎要求"首先" index是0
。
使用该逻辑,如果我对创建大小为3
的数组感兴趣,我应该写这个:
int[] newArray = new int[2] {1, 2, 3};
等一下...... VS发出错误,说an array initialize of length 2 is expected
。
因此,在循环数组和数组大小声明时,第一个索引是不一致的吗?前者使用基于0
的索引,第二个使用1
个索引。
这不是任何形式或方式的游戏破坏/改变,但我真的好奇为什么这里存在差异,或者地狱,如果这甚至是一个问题(如我说,它不会以任何方式破坏游戏,但我很好奇它为什么这样做。)
我现在可以想到为什么会使用基于1
的索引的原因:
在for循环中,您将使用< newArray.Length
而不是< newArray.Length - 1
或< newArray.Length
。
使用List
s一段时间,然后回到size-needs-be-declared-arrays,让我措手不及。
答案 0 :(得分:15)
因为您要声明数组中包含数字的元素。
我不确定这是不一致的。
你需要多少次看到切3块碎木?提示:不是3次。
另请注意,在帖子标题中,您错误地将数组大小声明称为“索引”。
答案 1 :(得分:5)
我认为你把索引器与长度混淆了。您希望在数组中包含三个元素(或变量),用
表示...new int[3]...
并且大括号中的元素是值,不是索引。指数仍为0。 Longform看起来像这样:
int[] newArray = new int[3];
newArray[0] = 1;
newArray[1] = 2;
newArray[2] = 3;
因此,您可以看到基于零的索引与int []的值相关的位置。
答案 2 :(得分:3)
int[] newArray = new int[2] {1, 2, 3};
在英语中,这将翻译为“我想要一个可容纳2件但放入3件物品的容器”。您将数组的长度(它可容纳多少项)与索引混淆到基于C语言的基于0的数组中(例如C) ,C ++,C#,Java,Javascript,Swift)。
另外,考虑一下数组索引究竟是什么(至少使用像C这样的低级语言);它是数组变量基址的内存偏移量。因此,arr[n]
转换为“获取arr
的地址,在内存中提前n * (the size of my type)
个字节,并在该计算的地址处给出值。因此,当n = 0时,您将引用该值在基本内存地址(数组的开头)。
答案 3 :(得分:2)
Wim Hollebrandse提供的答案绝对是伟大而正确的,但是想稍微扩展它以使OP更加理解为什么索引在大多数(但不是全部)语言中以0开头。
正如Wim所说,在声明时,它将在阵列中存储多少元素,这对于人类的理解是非常可口的。困扰很多的是为什么第一项实际上被称为第0项(即索引0)......原因是在数组中找到被搜索元素所需的简单数学。
数组中的所有元素按顺序存储在连续的块中。如果数组位于例如地址100并保持整数(每个大小为4个字节的整数),则在查找第一个项时,它将位于数组的开头,即地址100处。将在第一个或100 + 4 = 104地址之后立即存储。第3项存储在第2项或地址108之后。
因此,要计算第I个元素的位置,如果index以0开头,则数学很简单:
I-th-address = address_of_array + I * sizeof(datatype)
e.g. for our example it is 100 + i * 4
如果索引以1开头,则数学需要更多操作:
Ith-address - address of array + (I-1) * sizeof(datatype)
...这比基于0的效率低且不必要。
答案 4 :(得分:1)
您正在将数组的声明与数组元素的请求混合在一起。声明数组时,指定数组的长度(元素数),这是3,正确。当您请求元素时,您指定索引,并且第一个索引是0.但是您不应该混合索引和数组的长度。
在for循环中,你应该取< newArray.Length
:如果长度为3,那么循环将从0开始并经过索引0,1和2.然后它停止,因为3是不是&lt; 3。