Search

6.1 — Arrays (Part I)

In lesson 4.7 -- Structs, you learned that you can use a struct to aggregate many different data types into one identifier. This is great for the case where we want to model a single object that has many different properties. However, this is not so great for the case where we want to track many related instances of something.

Fortunately, structs are not the only aggregate data type in C++. An array is an aggregate data type that lets us access many variables of the same type through a single identifier.

Consider the case where you want to record the test scores for 30 students in a class. Without arrays, you would have to allocate 30 almost-identical variables!

Arrays give us a much easier way to do this. The following array definition is essentially equivalent:

In an array variable declaration, we use square brackets ([]) to tell the compiler both that this is an array variable (instead of a normal variable), as well as how many variables to allocate (called the array length).

In the above example, we declare a fixed array named testScore, with a length of 30. A fixed array (also called a fixed length array or fixed size array) is an array where the length is known at compile time. When testScore is instantiated, the compiler will allocate 30 integers.

Array elements and subscripting

Each of the variables in an array is called an element. Elements do not have their own unique names. Instead, to access individual elements of an array, we use the array name, along with the subscript operator ([]), and a parameter called a subscript (or index) that tells the compiler which element we want. This process is called subscripting or indexing the array.

In the example above, the first element in our array is testScore[0]. The second is testScore[1]. The tenth is testScore[9]. The last element in our testScore array is testScore[29]. This is great because we no longer need to keep track of a bunch of different (but related) names -- we can just vary the subscript to access different elements.

Important: Unlike everyday life, where we typically count starting from 1, in C++, arrays always count starting from 0!

For an array of length N, the array elements are numbered 0 through N-1! This is called the array’s range.

An example array program

Here’s a sample program that puts together the definition and indexing of an array:

This prints:

The lowest prime number is: 2
The sum of the first 5 primes is: 28

Array data types

Arrays can be made from any data type. Consider the following example, where we declare an array of doubles:

This program produces the result:

The average is 3.1

Arrays can also be made from structs. Consider the following example:

To access a struct member of an array element, first pick which array element you want, and then use the member selection operator to select the struct member you want:

Arrays can even be made from arrays, a topic that we’ll cover in a future lesson.

Array subscripts

In C++, array subscripts must always be an integral type (char, short, int, long, long long, etc… -- and strangely enough, bool). These subscripts can be either a constant or non-constant value.

Here are some examples:

Fixed array declarations

When declaring a fixed array, the length of the array (between the square brackets) must be a compile-time constant. This is because the length of a fixed array must be known at compile time. Here are some different ways to declare fixed arrays:

Note that in the last two cases, an error would result because length is not a compile-time constant.

A note on dynamic arrays

Because fixed arrays have memory allocated at compile time, that introduces two limitations:

  • Fixed arrays cannot have a length based on either user input or some other value calculated at runtime.
  • Fixed arrays have a fixed length that can not be changed.

In many cases, these limitations are problematic. Fortunately, C++ supports a second kind of array known as a dynamic array. The length of a dynamic array can be set at runtime, and their length can be changed. However, dynamic arrays are a little more complicated to instantiate, so we’ll cover them later in the chapter.

Summary

Fixed arrays provide an easy way to allocate and use multiple variables of the same type so long as the length of the array is known at compile time.

We’ll look at more topics around fixed arrays in the next lesson.

6.2 -- Arrays (Part II)
Index
5.x -- Chapter 5 comprehensive quiz

67 comments to 6.1 — Arrays (Part I)

  • Unz

    Hi, Thanks for all this, excellent site. My compiler lets me allocate an array using a user defined variable. (For example, the user can input the size of array, at runtime, it works fine). Am I mis-understanding this or is this a problem with my compiler? (I use Code::Blocks - MinGW)

    • Most compilers don’t conform precisely to the C++ spec. Many will let you “get away” with things that you technically shouldn’t be able to do. A good example is that most compilers will let you declare main() as returning void instead of int. Technically not part of the C++ spec, but compilers let you do it anyway. It may be that Code::Blocks is more permissive in how it lets you allocate arrays than is defined in the C++ spec.

      • Unz

        Of course you are correct (never much doubt was there!). But the unusual behaviour wasn’t with Code::Blocks itself. While still using Code::Blocks, I changed the default compiler from the GNU GCC that I usually use, to MS Visual 2005/2008. And then it refused to compile (for the same reasons you mention).

        Seems MinGW GCC compiler is a little more lenient, in this respect at least.
        (Which is just as well because I can’t think of another solution to my problem.
        Thanks again. This site is exactly what I need. Its **easily** the best around & I hope you’re doing OK out of it.)

        • Eugene Wee

          What you are looking at is the effect of a compiler extension. In the 1999 edition of the C Standard (not C++, but C), a feature known as “variable length arrays” was introduced. The GNU C compiler implemented this feature, and it was ported over to the GNU C++ compiler as a compiler extension. As such, the MinGW port of g++ has this compiler extension.

          To disable such compiler extensions when compiling with g++, use the -pedantic option.

          Note that Code::Blocks is not a compiler, but an IDE. The compiler is the MinGW port of g++.

        • csvan

          There is a way to work around this - its a bit of overkill at this part of the tutorial, but you can use dynamic arrays to get around this limitation in VS:

          you can now use the pointer myArray (see later on in this tutorial how pointers work!) ALMOST as an array. I say almost because I think I have heard somewhere that pointers and arrays are NOT functionally equivalent, although they seem to be at face value.

          Hope it helps! Mail me if you have any problems with what I wrote (csvanefalk@hushmail.me)

          Keep coding. Use it for good 🙂

          EDIT: Note that the above dynamic array is declared for ints! If you want an array of doubles, I think you have to do the same thing for doubles (although the variable size itself should still be able to be an int, as it only defines the size of the array, not its content).

      • Abdul sami

        thanks Admin ,you are doing a good job ,what a great site to clear CPP concepts.i am facing same problem .Dev c++ compile  also works fine with this problem,could you please explain it deeply .thanks in advance
           To dear Alex

        • Alex

          C99 allows users to define variable length arrays (arrays with a length defined at runtime instead of compile time). Even though C++ does not officially support this, some compilers will allow it because C99 does.

  • is asscociative array can also be done in c++?

  • Harsh

    In this particular program is there any kind of memory leakage if the program is compiled in :-
    1) C
    2) C++

    • Alex

      No in both cases. One of the nice things about fixed arrays is that (just like normal local variables) they handle their own memory allocation and deallocation.

  • mariusrazvan

    First of all i love what you did here… its a great thing,

    second, i have a doubt… you said that “Arrays can hold any data type, including floating point values and even structs” … can it hold char type too? tried but it only holds chars till it finds empty space…
    i want something like
    cout << "enter your text here" <> rawtext;

    cout << "your text is:" << rawtext << endl;
    // and i want the output: enter your text here
    // but i only get the first word…
    // if i input enteryourtexthere i get all the text as output…

    so my problem is with the empty space between the words…

  • astronaut13

    Would an array be good if, say, I was making a game that had an inventory, and I wanted to use the array for all the have/don’t have variables? Or is there a better way?

    • It really depends on how the inventory is implemented.

      • Alex

        Agree with Zingmars. There are multiple ways to set up an inventory, and which is most appropriate really depends on your situation.

        Generally speaking, arrays are an excellent way of implementing inventories. If the number of items in the game is small and the user could own all of them at once, then you could do an array like this:

        If the number of items is large and the user can only hold a certain number of them at once, you could do an array like this:

  • sufy

    Wait… if C++ won’t let you do:

    cin >> nVar;
    int aArray[nVar];

    Can’t you just do:

    int nVar;
    cin >> nVar; // This can be replaced with anything that gives nVar a value.
    const int nArray = nVar;
    int someArray[nVar];

    Thereby easily bypassing the inability to give an array a variable size! 😀

    …I think :-/

    • sufy

      Oops make that:

      int nVar;
      cin >> nVar; // This can be replaced with anything that gives nVar a value.
      const int nArray = nVar;
      int someArray[nArray];

  • Hossein

    Thank you for the great documentation 🙂
    By the way on the latest compiler versions ( starting from gcc 4.3+ and possibly VC++ 10) arrays size can be dynamically specified at run-time meaning now the statement below:
    int nSize = 5;
    int anArray[nSize]; //Is Ok in the latest compiler versions such as gcc (4.3+) and VC++10+

    is pretty fine and will compile just fine.
    So it would be a good idea to update the documentation to address new changes .
    Regards

    • Alex

      Variable length arrays are not part of the C++ specification, even though some compilers support them for C99 compatibility. I recommend their use be avoided entirely (there are other ways to do the same thing).

  • gmarwaha

    In my problem I don’t know what would be the size of my array - is there a way around it? I get the size info. from a bunch of different functions.

    I know the maximum size of the array but I don’t want an array with empty (non-relevant) values since that would affect my calculations.

    Ideas, anyone?

    • Alex

      If you don’t know what size your arrays will be in advance of runtime, then fixed arrays aren’t for you. You could try dynamic arrays, or even better, use std::vector.

  • prabs

    #include<iostream>
    using namespace std;

    int main()
    {
      int i=10;
      int arr[i];
      getchar();
      return 0;
      
    }

    Will this program compile or not…….?

  • Danny

    Hey Alex,

    It looks like initializing arrays with non-constant variables works fine in my g++ compiler, and I’ve seen a couple of comments on this article and another stating that it works fine as well. Is this a new C++ feature or something?

    Thanks again for the awesome site.

    • Alex

      No. The ability to set the size of a fixed array with a non-const variable was introduced as part of the C99 update. It has not been incorporated into C++ (at least as of C++14).

      Some compilers may support it for C99 compatibility reasons, but you should generally avoid it.

  • Arrays must be constant, are you kidding me? Sure they should when possible, but for a lot of data structures it’s necessary to have variable length arrays, take arraylists, merge sort and other algorithms, there you cannot know the array length before compile time. I do believe what was intended is, do not use variable length arrays when you can use a constant length.

    • Alex

      The article meant what it says. 🙂 Standard arrays in C++ must have a constant length. C++ is primitive this way.

      Fortunately, there are workarounds. C++ supports dynamic arrays using operators new and delete (but you have to do the memory management). Most people use a class to abstract the memory management portion away from the user (either via std::vector, or by writing their own templated array classes).

  • Hey Alex, first of all thank you so much for the tutorials. My question is how to work with graphics in C++…? Whenever I run my programs, the result is given through command prompt. How to start building software that deals with graphics..?

    • Alex

      Doing graphics will require either using OS-level functionality, or installing some kind of toolkit or library. If you want to create GUI applications, you can check out QT. If you want to create a graphical application (2d or 3d), check out SDL.

  • What do you mean by OS-level functionality

    • Alex

      Operating systems such as Windows often include functionality to do user-interface or basic graphics.

      Personally, I’d avoid these, as they’re not cross-platform compatible.

  • I think dynamic array size (run time constant) allocation is dependent on compiler. It doesn’t necessarily have to be a compile time constant.
    The following code works on Linux, GCC compiler. I tried compiling it with -std=c++11 and without this flag. It works both times.

    [link]https://stackoverflow.com/questions/737240/c-c-array-size-at-run-time-w-o-dynamic-allocation-is-allowed[/link] Apparently this has been updated in c++99 standard and also in C++ 14

    I don’t know if this is a bad practice or frowned upon.

    • Alex

      A few things:
      * There is no C++99 standard. There IS a C99 standard that introduced new features into the C language (including variable length arrays). Features adopted into C99 are not automatically included in C++.
      * Although variable length arrays were in the C++14 draft standard for a while, it appears they were removed before the final draft. Consequently, they are not officially supported in C++.
      * Some compilers still support them for backwards compatibility reasons. However, because they are not an official part of the C++ language, best practice would be to not use them. Use std::vector instead, as it probably does what you want anyway.

  • Nitin Singh

    The output of first example of array’s program needs some attention!

  • Hi Alex,
    we know that the name of an array is a pointer to the first element of the array.

    if we compile this program the output will be something like this ~~~> 0x22fe30

    But why this is not true for chars :

    this program’s output will be this ~~~> Hello

  • Jim

    Alex,
    Your spelled is not consistent above. int testScoreStudent and int testScores[xx]. to many or to few ‘s’.

    Great tutorial Thanks

  • Jim

    Alex,
    I’m a bit confused about what you’ve wrote here. "In C++, array subscripts must always be an integral type (char, short, int, long, long long, etc… -- and strangely enough, bool). These subscripts can be either a constant or non-constant value."

    Do you mean we can use any of these in place of the xxx in array[xxx]? If so then how is char handled in this case?

    • Alex

      Yes, all of the following are valid syntactically:

  • Aryan

    Hey Alex!

    I was studying about vectors a while ago and I am confused as to what is the major difference between a vector and an array.
    A vector also stores more than one values of the same type. An array’s element’s naming is also the same as vector’s so whats the difference?

    • Alex

      In C++, a vector is an array class that can dynamically resize itself. At the end of this chapter there is an introduction to vectors. Once you read through this chapter, you should understand the difference between:
      * A built-in fixed array
      * A built-in dynamic array
      * std::array
      * std::vector

  • suman khan

    please send me a tic-tac-toc game cooding in c++

  • HelloWorld

    As you say in the end, the indexing starts at zero, so if I want to store 30 integers, it would be enough to define an int array of [29](30 entrys), right?

    I mean this:

    int testScoreStudent[29];

    is the same as:

    int testScoreStudent0;
    int testScoreStudent1;
    ..
    int testScoreStudent29;
    _______
    This allocates memory for an integer 30 times, right?

    So why would you define an array of [30]
    (31 integer allocations(in memory))?

    Please correct me if i am wrong, but isn’t the first/last one actually wasted? If I work with the sizeof operator on this array, would the result be correct ?
    I am not sure about this because - in your example the first array entry [0] “int testScoreStudent[0]; ist defined, but not initialized, right ? How does this affect the size, length of the array(e.g if i work with loops)?

    sorry but I am pretty new to cpp

    • HelloWorld

      The last paragraph of my post is wrong: "In your example the first array entry [0] “int testScoreStudent[0]; is defined, but not initialized, right ?" Actually nothing is initialized right? Just defined?

      I actually meant, that
      testScoreStudent[0] would be the same as testScorestudent1, in your first example.
      Following this logic the last array entry would be testScoreStudent[29] same as testScoreStudent30;

    • Alex

      When you do int testScoreStudent[30], you’re allocating an array of 30 elements. These elements have indices 0 through 29. The size of the array is always one greater than the index of the last element.

  • bert

    Typo (well, missing word)

    In an (array) variable declaration, we use square brackets ([]) to tell the compiler both that this is an array variable (instead of a normal variable), as well as how many variables to allocate (called the array length).

  • Anddo

    Just note, surprisingly, on XCode 7.3.1, this worked. Compiled and run !!

    Not on visual studio 2015 though !

    • Anddo

      UPDATE: it seems that it’s gcc compatibility problem. Using LLVM with Clang, there is solution to disable such behavior in XCode. This is quote from LLVM site

      "GCC and C99 allow an array’s size to be determined at run time. This extension is not permitted in standard C++. However, Clang supports such variable length arrays for compatibility with GNU C and C99 programs.

      If you would prefer not to use this extension, you can disable it with -Werror=vla."

    • Alex

      Yup. Some C++ compilers support this for C99 compatibility reasons, others don’t. Because it’s not part of the C++ specification, I recommend avoiding using this for now.

  • raj

    i don’t get the idea of fixed sized array.you said fixed arrays are of fixed length,if that’s true about fixed arrays than the array should be holding only a fixed number of elements and using the variable you should only be allowed to navigate through that range i.e assuming an array ARR is of fixed size 4 you should only be allowed to access from indexes 0-3 and beyond that is outside the fixed sized array(ARR) range i.e indexes 4,5,6 and so on.
    my compiler lets me do this:
    const int len=10;
    int arr[len];
    //accepting elements even beyond fixed range
    for(int i=0;i<15;i++)
    cin>>arr[i];

    //accessing elements beyond array range
    cout<<arr[10]<<" "<<arr[11]<<" "<<arr[12]<<" "<<arr[13]<<" "<<arr[14];

    while accepting user input and also while printing values to the console shouldn’t the compiler be throwing exception since we are going beyond the defined range.

    • Alex

      It sounds like you get the idea of fixed size arrays, you’re just balking at the lack of any kind of range-checking. Which is indeed the case: neither the compiler nor the program itself do any kind of compile-time or runtime range-checking for C-style fixed arrays. It’s part of C++’s mantra of “trust the programmer”.

      If you want runtime range-checking, use std::array from the standard library (which we cover later in this chapter) along with the at() function (instead of []) to access the elements.

Leave a Comment

Put C++ code inside [code][/code] tags to use the syntax highlighter