Why programmers should always start counting from zero

When you want to perform the same action n times, there are two common ways of writing the loop:

for (int i = 0; i < n; i++) {
// do stuff
}

or

for (int i = 1; i <= n; i++) {
// do stuff
}

And both work, but why is the first one better? (besides the obvious fact that it matches with the iteration on zero-based array indices).

  1. Counting from zero encourages us to use asymmetric ranges to express intervals. [0, rows) instead of [1, rows] and that’s easier to use because [m, n) has n-m elements, while [m, n] has n-m+1. So, the number of elements in [0, rows) is obviously rows-0=rows but in [1, rows] it is not as obvious.
    And as we all know, there are only two hard things in Computer Science: cache invalidation, naming things and off-by-one errors.
  2. Asymmetric ranges represent better an empty interval: you would use [n, n) instead of [n, n-1] to do it.
  3. It makes easier to express loop invariants:
// loop invariant: i lines have been processed
for (int i = 0; i < rows; i++) {
// do stuff..
}
// loop invariant: i lines have been processed

    Felipe Ribeiro

    Written by

    Senior Software Engineer @ Netflix, previously Staff Engineer @ Spotify. And when singularity comes, I’ll probably be on _their_ side 🤖.

    Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
    Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
    Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade