start arrays at 0 or 1

0 or 1 is the question.

Arrays in C++ start at 0.

However, sometimes it is more convenient to start them at 1.
For example, if I am to model a chess board as an array, I feel it is more convenient to number rows and columns between 1 and 8, rather than between 0 and 7.

If I have 3 items of something, I'd rather count them 1,2,3, instead of 0,1,2.

Hence, the question:  is this a matter of taste, or are there practical ways when you do need to use 0, or to use 1.

Just to note:  there are some things that are a matter of taste, but then someone comes up with a good reason to use one of those things and not the others.  That's why I'm asking.

If I get a really good reason or a really good reply, I will increase points before awarding points.
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

As you state, it's a simple fact that C++ indexes arrays starting at 0.

The beauty of OO is that you can easily construct a class that separates this implementation detail (0 base) from your model (a chess board with row numbers starting at 1).

So you could do something like this...

template <class T>
class OneBasedArray {
    int m_size;
    T *m_array;
OneBasedArray(int size) {
    m_size = size;
    m_array = new T[size]; }
~OneBasedArray(int size) {
    delete [] m_array }
T& operator[](int i) {
    ASSERT(i > 0 && i <= m_size);  
    return m_array[i-1]; }

Now I can say
OneBasedArray<myClass> arr(3);
arr[1] = something...

(Sorry, no compiler here, so this is just the gist of it.  But you get the idea.)


- Frank
dennismvAuthor Commented:
hmm that's pretty good
Actually, I didn't expect this kind of reply.
It puts 0-based and 1-based together in a way that is a win-win situation -- no wasted space since you don't ignore array[0] and base 1 if you're into that.

>>It puts 0-based and 1-based together in a way that is a win-win situation -- no wasted space since you don't ignore array[0]
>>and base 1 if you're into that.

I would not recommend that approach, nor would I recommend trying to use a 1 base index just for convenience.

It adds to much ambiguity to the code, and makes it harder to debug, especially if you're not the author of the code.

Most modern languages use zero based indexes, so it's to your benefit to get used to this paradigm.

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Cloud Class® Course: C++ 11 Fundamentals

This course will introduce you to C++ 11 and teach you about syntax fundamentals.

I agree whole-heartedly with Axter on this one.  Learn to be comfortable with 0-based arrays -- don't try to create work-arounds for features that are built into the language.  This is just asking for a maintenance nightmare!.

dennismvAuthor Commented:

well is there a reason as to why 0-based convention for arrays was picked ?


All non-negative values have to be used for memory addressing, and so as for array indexing. why should we waste one number for indexing???


not yet?

for instance , using an integer as array index causes the array to be addressable for 2^16=65536 elements of array..what would happen if you would not be able to use 0 as array index?.......In case, for just one last 65536th element, you would have to change the index variable from integer to a more mamory occupying variable....

There are other drawbacks also....(only one to explain took my 10 minutes ;-p  )


If arrays started at 1, then 0 would be out of bounds. If I mistyped 0 somewhere, I'd have a memory corruption. If arrays start at 0 however, then I have to mistype -1 in order to corrupt it. Starting arrays at 0 would seem to decrease the chance of a memory error off of a typo on the index. Also, if an index were used to traverse the array, the index could not be used to the full extent of its size. There would be 2^(sizeof(T)*8) - 1 possible objects, as opposed to 2^(sizeof(T)*8).
At the lowest level, the compiler needs to come up with an address for an indexed array reference.  The array is the base address and then the byte offset from that to get to the Nth element is
   offset = sizeof(T) * index
if I have a 1 based array and I don't want to allocate and not use the first element, my offset calculation has to be
   offset = sizeof(T) * (index - 1)

That subtraction in every array reference makes 1 based arrays more expensive.  So you spend either space or time using 1 based arrays.  That's why most languages use 0 based arrays.

With respect to kledbetter's comment, I respectfully disagree about the need to "get used to it".  As I stated in my initial post, 0 basedness is a fact of the language.  But that doesn't mean I shouldn't use classes to allow me to express my program in terms of the domain data model.  

For example, Excel sheets start with Row 1.  Users are comfortable with this.  The fact that the app is written in C++ shouldn't require that users change their model of a spreadsheet.  So at some point in the Excel implementation there is a mapping from the user's numbering of rows to the applications data storage model.  I think there's a lot of +1 and -1 going on translating between storage model and user model.  And I suspect that the developers have hidden that within a class representation so that they don't have to be worrying about it throughout their application.  You can have your cake (domain model representation) while still working with the rules of the language.

- Frank
dennismvAuthor Commented:

Ok, I see, on the low level we are working with bits.
If we want all 65536 values, we better do 0...65535
Anything larger will overflow.

About mistyping the index, I don't think mistyping is a big problem.  If it was known fact that arrays start at 1, then these mistypes would be rare.
>>But that doesn't mean I shouldn't use classes to allow me to express my program in terms of the domain data model.  

It means (in general) it's a bad idea to create classes that do not use the same paradigm as the language.
You're adding ambiguity to the code, which will make it harder to debug, and easier to introduce new bugs.

This is a bad idea all around.
There's very little upside, and a lot of downside to this approach.

If you use this approach, you would have to mix and match zero based logic with one based logic.
Or you would have to create classes for every object you used in your code.
That would mean you would have to create your own std::string, std::vector, std::iostream.
You would also have to replace many of the C-Standard-Functions which are zero based.

If you're not willing to replace all these objects and C-Functions, then you're going to have complex code mixing one based objects with zero based objects/functions.
I agree that it would be a monumental waste of time to recreate standard libraries to be 1 based.  There's no point.  That's because the domain of class string is C++ programming.  And we're all used to 0 based data types so we should stick with that as domain appropriate.

However, you should create application class interfaces that reflect the domain of the application, not the language.  If I'm writing Excel and we talk about Row 1 on screen, I should be able to continue talking about Row 1 in the code.
Besides memory addressing, in the past, I wondered so much about using 0-based array in C++ because in some programs I think it's better to use 1-based array. Later I found out that using 0-based array is more convenient than using 1-based array (just only it looks not so good in the first stage of analysis) in using the formula, for example ... If you want to control your chess-man not to jump out of the board [0..7] when you increase or decrease it ... then it's quite clear to apply this fomula,  

(x + 1) % 8 or (x - 1) % 8

I know this is not the really reason, but it flavors to use the 0-based array.

Moreover, if you would like to use the array for example from 10 to 99 , then I think the good way is to shift your index from 0 to 89 ... For instance,

#define SHIFT(x) ((x) - 10)

int A[90] ; // A[0] ... A[89]

So in your programs, just use SHIFT(x) instead of x to index your array.
Numerical Recipies have a one based array implementation:

Essentially, since 'C' arrays are just pointers, it is possible to create your 1-dimensional array as:

    float *a0 = calloc(  size_of_array, sizeof( float ) );  // zero based;

    float *a1 = calloc(  size_of_array, sizeof( float ) );
             a1 = &( a1[-1] );   // one based;

You can now access a1[n], which will be the 'n'th element.


Note that there is no additional overhead to using this type of indexing.

IMHO:  This is useful for speed, for but not easy to document.  If you can spare the horsepower, use a class.

It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.