Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

In C++ and C the iteration idiom almost always looks like:

  for (elementIndex = first-element; elementIndex < indexAfterLastElement; elementIndex++) {
  ... 
  }
That is, writing the equivalent of the mathematical notation:

  firstElementIndex <= elementIndex < indexAfterLastElement
Two advantages of that idiom:

The first one is that indexAfterLastElement - firstElementIndex equals the number of elements being scanned.

The second advantage (which is the most debatable, and personal) is that the initial boundary condition is trivial (it's the first element) and the end boundary condition is natural i.e. just look past the element you are looking at whether there is a next one. That's what Dijkstra is talking about when telling the example of the student who would not look past the end of the page.

I used the epithet natural because for most of the objects we interact with, the end is not part of the object, rather it is the transition in between the last element and nothingness.

Now that said (in too many words) if you compare 1-based arrays and 0-based arrays you have:

  for (i = 0; i < N; i++) {
  ...
  }

  for (i = 1; i < N + 1; i++) {
  ...
  }
Both would be acceptable. However 0 based arrays have the advantage of giving i two meanings:

  1. the index of the current element
  2. the number of elements scanned so far.
At the end of the iteration, i also conveniently contains the number of elements having been scanned. Which can be useful in algorithms where there is an extra condition which might let you leave the iteration early.

This to me is the most important part, zero-based indexing is more expressive.



These are some of the best arguments for 0-based indexing, and I agree that these are very useful properties. In my day-to-day programming though, the 1-based indexing has some (admittedly, less math-based) advantages too. For instance when I have an array my brain appreciates the simplicity of the "oh, this array has 10 elements. What's the last element? Number 10! Yay, that was easy" thought process.

In many cases I don't care about specifying boundary conditions at all; I will just use something along the lines of

  for i, v in ipairs(t) do something_interesting(i, v) end
or even just a map or fold or some other iteration technique where I'm not explicitly specifying boundary conditions. If I'm implementing a heap or some other data structure which uses calculations to interact with an array I will be double-checking my math anyway because I don't trust myself to get it right the first time, 0-based indexing or not ;)


The last element of an array is foo[-1] regardless of it's length. :-) And try implementing a circular buffer using an array of N elements with 1-based indexing and then 0-based. Sorry in advance for the loss of hair due to the former.


you mean like array[mod(i, length) + 1]




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: