start arrays at 0 or 1

Posted on 2004-11-18
Last Modified: 2010-04-01
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.
Question by:dennismv
    LVL 3

    Assisted Solution

    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

    Author Comment

    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.

    LVL 30

    Accepted Solution

    >>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.

    Expert Comment

    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!.


    Author Comment


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

    Assisted Solution



    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  )


    LVL 3

    Expert Comment

    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).
    LVL 3

    Expert Comment

    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

    Author Comment


    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.
    LVL 30

    Expert Comment

    >>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.
    LVL 3

    Expert Comment

    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.
    LVL 1

    Expert Comment

    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.

    Expert Comment

    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.


    Write Comment

    Please enter a first name

    Please enter a last name

    We will never share this with anyone.

    Featured Post

    Enabling OSINT in Activity Based Intelligence

    Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

    Article by: SunnyDark
    This article's goal is to present you with an easy to use XML wrapper for C++ and also present some interesting techniques that you might use with MS C++. The reason I built this class is to ease the pain of using XML files with C++, since there is…
    Container Orchestration platforms empower organizations to scale their apps at an exceptional rate. This is the reason numerous innovation-driven companies are moving apps to an appropriated datacenter wide platform that empowers them to scale at a …
    The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.
    The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

    760 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    8 Experts available now in Live!

    Get 1:1 Help Now