C语言 为什么索引从“C”中的零开始?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7320686/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why does the indexing start with zero in 'C'?
提问by Nitish Pareek
Why does the indexing in an array start with zero in C and not with 1?
为什么数组中的索引在 C 中从零开始而不是从 1 开始?
回答by Massimiliano Peluso
In C, the name of an array is essentially a pointer, a reference to a memory location, and so the expression array[n] refers to a memory location n-elements away from the starting element. This means that the index is used as an offset. The first element of the array is exactly contained in the memory location that array refers (0 elements away), so it should be denoted as array[0].
在 C 中,数组的名称本质上是一个指针,一个对内存位置的引用,因此表达式 array[n] 指的是距起始元素 n 个元素的内存位置。这意味着索引用作偏移量。数组的第一个元素正好包含在数组引用的内存位置(0 个元素之外),所以它应该表示为数组 [0]。
for more info:
更多信息:
http://developeronline.blogspot.com/2008/04/why-array-index-should-start-from-0.html
http://developeronline.blogspot.com/2008/04/why-array-index-should-start-from-0.html
回答by Anirudh Ramanathan
This question was posted over a year ago, but here goes...
这个问题是一年多前发布的,但在这里......
About the above reasons
关于以上原因
While Dijkstra's article(previously referenced in a now-deleted answer) makes sense from a mathematical perspective, it isn't as relevantwhen it comes to programming.
虽然Dijkstra 的文章(以前在现已删除的答案中引用)从数学角度来看是有道理的,但在编程方面却没有那么重要。
The decision taken by the language specification & compiler-designers is based on the decision made by computer system-designers to start count at 0.
语言规范和编译器设计人员做出的决定是基于计算机系统设计人员做出的从 0 开始计数的决定。
The probable reason
可能的原因
Quoting from a Plea for Peaceby Danny Cohen.
引用丹尼·科恩 (Danny Cohen) 的和平请求。
For any base b, the first b^Nnon-negative integers are represented by exactly Ndigits (including leading zeros) only if numbering starts at 0.
对于任何基数 b,仅当编号从 0 开始时,前b^N 个非负整数才由恰好N 个数字(包括前导零)表示。
This can be tested quite easily. In base-2, take 2^3 = 8The 8th number is:
这可以很容易地进行测试。在 base-2 中,取2^3 = 8第 8 个数字是:
- 8 (binary: 1000) if we start count at 1
- 7 (binary: 111) if we start count at 0
- 8(二进制:1000)如果我们从 1 开始计数
- 7(二进制:111)如果我们从 0 开始计数
111can be represented using 3bits, while 1000will require an extra bit (4 bits).
111可以使用3位表示,而1000需要额外的位(4 位)。
Why is this relevant
为什么这是相关的
Computer memory addresses have 2^Ncells addressed by Nbits. Now if we start counting at 1, 2^Ncells would need N+1address lines. The extra-bit is needed to access exactly 1 address. (1000in the above case.). Another way to solve it would be to leave the last address inaccessible, and use Naddress lines.
计算机内存地址具有2^N按N位寻址的单元格。现在,如果我们从 1 开始计数,2^N单元格将需要N+1地址线。需要额外的位来访问正好 1 个地址。(1000在上述情况下。)。另一种解决方法是让最后一个地址不可访问,并使用N地址线。
Both are sub-optimal solutions, compared to starting count at 0, which would keep all addresses accessible, using exactly Naddress lines!
两者都是次优解决方案,与从 0 开始计数相比,这将保持所有地址可访问,使用准确的N地址线!
Conclusion
结论
The decision to start count at 0, has since permeated all digital systems, including the software running on them, because it makes it simpler for the code to translate to what the underlying system can interpret. If it weren't so, there would be one unnecessary translation operation between the machine and programmer, for every array access. It makes compilation easier.
从 开始计数的决定0已渗透到所有数字系统,包括在其上运行的软件,因为它使代码更容易转换为底层系统可以解释的内容。如果不是这样,对于每次数组访问,机器和程序员之间都会有一个不必要的转换操作。它使编译更容易。
Quoting from the paper:
引自论文:


回答by Doug T.
Because 0 is how far from the pointer to the head of the array to the array's first element.
因为 0 是指向数组头的指针到数组第一个元素的距离。
Consider:
考虑:
int foo[5] = {1,2,3,4,5};
To access 0 we do:
要访问 0,我们执行以下操作:
foo[0]
But foo decomposes to a pointer, and the above access has analogous pointer arithmetic way of accessing it
但是 foo 分解为一个指针,上面的访问有类似的指针运算方式来访问它
*(foo + 0)
These days pointer arithmetic isn't used as frequently. Way back when though, it was a convenient way to take an address and move X "ints" away from that starting point. Of course if you wanted to just stay where you are, you just add 0!
如今,指针算法的使用频率不高。回到过去,这是一种获取地址并将 X 个“整数”从该起点移开的便捷方法。当然,如果你只想呆在原地,你只需加0!
回答by Branko Dimitrijevic
Because 0-based index allows...
因为基于 0 的索引允许...
array[index]
...to be implemented as...
......实施为......
*(array + index)
If index were 1-based, compiler would need to generate: *(array + index - 1), and this "-1" would hurt the performance.
如果索引是基于 1 的,编译器将需要生成: *(array + index - 1),而这个“-1”会损害性能。
回答by progrmr
Because it made the compiler and linker simpler (easier to write).
因为它使编译器和链接器更简单(更容易编写)。
参考:
"...Referencing memory by an address and an offset is represented directly in hardware on virtually all computer architectures, so this design detail in C makes compilation easier"
“...通过地址和偏移量引用内存在几乎所有计算机体系结构上都直接在硬件中表示,因此 C 中的这种设计细节使编译更容易”
and
和
"...this makes for a simpler implementation..."
“......这使得实现更简单......”
回答by R.. GitHub STOP HELPING ICE
For the same reason that, when it's Wednesday and somebody asks you how many days til Wednesday, you say 0 rather than 1, and that when it's Wednesday and somebody asks you how many days until Thursday, you say 1 rather than 2.
出于同样的原因,当星期三有人问你到星期三还有多少天时,你说 0 而不是 1,而当星期三有人问你离星期四还有多少天时,你说 1 而不是 2。
回答by Amit Prakash
Array index always starts with zero.Let assume base address is 2000. Now arr[i] = *(arr+i). Now if i= 0, this means *(2000+0)is equal to base address or address of first element in array. this index is treated as offset, so bydeafault index starts from zero.
数组索引总是从零开始。假设基地址是 2000。现在arr[i] = *(arr+i)。现在if i= 0,这意味着*(2000+0) 等于基地址或数组中第一个元素的地址。此索引被视为偏移量,因此默认索引从零开始。
回答by supercat
The most elegant explanation I've read for zero-based numbering is an observation that values aren't stored at the marked places on the number line, but rather in the spaces between them. The first item is stored between zero and one, the next between one and two, etc. The Nth item is stored between N-1 and N. A range of items may be described using the numbers on either side. Individual items are by convention described using the numbers below it. If one is given a range (X,Y), identifying individual numbers using the number below means that one can identify the first item without using any arithmetic (it's item X) but one must subtract one from Y to identify the last item (Y-1). Identifying items using the number above would make it easier to identify the last item in a range (it would be item Y), but harder to identify the first (X+1).
我读过的关于从零开始编号的最优雅的解释是观察到值不是存储在数轴上的标记位置,而是存储在它们之间的空间中。第一个项目存储在 0 和 1 之间,下一个项目存储在 1 和 2 之间,等等。第 N 个项目存储在 N-1 和 N 之间。可以使用任一侧的数字来描述一系列项目。个别项目按照惯例使用其下方的数字进行描述。如果给定一个范围 (X,Y),使用下面的数字识别单个数字意味着可以不使用任何算术识别第一个项目(它的项目 X),但必须从 Y 中减去一个才能识别最后一个项目(Y -1). 使用上面的数字识别项目可以更容易地识别范围中的最后一个项目(它将是项目 Y),
Although it wouldn't be horrible to identify items based upon the number above them, defining the first item in the range (X,Y) as being the one above X generally works out more nicely than defining it as the one below (X+1).
虽然根据上面的数字来识别项目并不可怕,但将范围 (X,Y) 中的第一个项目定义为 X 上方的项目通常比将其定义为下面的项目 (X+ 1)。
回答by Gianluca Ghettini
Try to access a pixel screen using X,Y coordinates on a 1-based matrix. The formula is utterly complex. Why is complex? Because you end up converting the X,Y coords into one number, the offset. Why you need to convert X,Y to an offset? Because that's how memory is organized inside computers, as a continuous stream of memory cells (arrays). How computers deals with array cells? Using offsets (displacements from the first cell, a zero-based indexing model).
尝试使用基于 1 的矩阵上的 X,Y 坐标访问像素屏幕。公式非常复杂。为什么复杂?因为您最终将 X、Y 坐标转换为一个数字,即偏移量。为什么需要将 X,Y 转换为偏移量?因为这就是计算机内部内存的组织方式,作为内存单元(阵列)的连续流。计算机如何处理阵列单元?使用偏移量(第一个单元格的位移,基于零的索引模型)。
So at some point in the code you need (or the compiler needs) to convert the 1-base formula to a 0-based formula because that's how computers deal with memory.
因此,在代码中的某个时刻,您需要(或编译器需要)将基于 1 的公式转换为基于 0 的公式,因为这就是计算机处理内存的方式。
回答by Rob
The technical reason might derive from the fact that the pointer to a memory location of an array is the contents of the first element of the array. If you declare the pointer with an index of one, programs would normally add that value of one to the pointer to access the content which is not what you want, of course.
技术原因可能源于这样一个事实,即指向数组内存位置的指针是数组第一个元素的内容。如果您声明指针的索引为 1,程序通常会将该值 1 添加到指针以访问您不想要的内容,当然。

