What are arrays?

An array is a collection of the same type of elements that are stored in a contiguous memorycontinuous blocks of memory location.

Think of an array as a bookshelf that has several books placed on it. We can say that we have an array of books. Now, suppose we wish to read the book, The Art of Computer Programming (placed on the 5th location on the shelf). We’ll have to access the book (element) from the shelf (array).

We can do this in two ways:

  • We either fetch the fifth book (element) directly.

  • In case we don’t know which place (index) the book is, we’ll have to traverse the shelf (array) from the first index to the index on which the book is placed.

In C/C++, the indexing of arrays starts from 0 and not 1. In some languages, the array indexing starts from 1.

Why do we need arrays?

With arrays, we can store a number of similar data elements together and can easily access elements, compare them with each other, or even arrange them as needed.

Remember what we did to find the maximum number out of different numbers? We stored each number in a different variable and then compared the first value (assumed to be the maximum) with all values and updated the max accordingly.

We can use this method if the total numbers are 5, 10, or even 15. But what if there are a total of 50, 100, or 1 million numbers, and we need to find the maximum number? We can’t possibly think of making 50 or 100, or 1 million variables to store all those numbers. That would be too tiring and boring!

In such cases, our go-to solution is the arrays! With arrays, we can store a large number of the same type of data. Not only that, we can traverse through them efficiently.

Let’s discuss this powerful idea of arrays in C++.

Syntax of declaring an array

In C++, the syntax used to declare an array is as follows:

datatype array_name[const_int_size];

For example,

float marks[10];

Here, we declared an array named marks of type float and size 10. This array can hold 10 floating-point values.

There are two types of arrays:

Types of array

  • Single-dimensional array
  • Multi-dimensional array

Visualizing the arrays

Look at the following code snippet:

Press + to interact
int num1=2;
.
.
.
int num2 = 8, num3 = 9;
.
.
.
int num4 = 1;
.
....
int A[4] = {2,8,9,1};

If we look at the illustration below, we have four variables, namely num1, num2, num3, and num4, residing in a memory block, and they may not be contiguous.

Press + to interact
Variables in memory
Variables in memory

With arrays, all four values, int A[4]={2,8,9,1}, are stored in a contiguous memory location. For simplicity’s sake, we’ve shortened the hexadecimal addresses appearing in the illustration. However, if we observe, the address of each value is incremented by 4 because each integer value takes 4 bytes.

For a bool type array, each element of the array would take 1 byte (not 4) of memory because the bool type uses 1 byte to store a true or false value. The increment in address is dependent on the data type of the array.

The indexing of an array starts from 0 and goes up to size-1.

Press + to interact
Memory of array
Memory of array

How to use arrays

There are many ways to access the elements of an array. We’ll learn about them as we go through the lesson.

In the illustration above, we declared an array A where the first element is A[0], which stores 2. The second element is A[1], which holds 8, and so on.

The last value is at index size-1 (4 - 1 = 3), so A[3] is the last value.

We can think about the array name as the base address of the first memory location and these indices as the offset, i.e., how much we have to move forward from the base address.

Now that we’re done with the basics, let’s see how we can declare and initialize an array.

Declaring and initializing arrays

In the program below, we declare and initialize an array and then print the values stored inside of the array.

Array declaration

Let’s say we create an array of integers called A of size 5 (meaning we can store 5 integer type values):

int A[5];

If we want to print the array elements, we would only get the garbage values. This is because we haven’t initialized the array yet.

Run the code below to see what happens when we print the array’s values without initializing them first. Step by step, execute the program and see in the memory:

#include <iostream>
using namespace std;

int main()
{
    int A[5]; // All values will be garbage
    
    // printing the values stored inside the array
    
    cout << A[0]<<" "<<'\n';  // garbage value at zeroth index
    cout << A[1]<<" "<<'\n';  // garbage value at first index
    cout << A[2]<<" "<<'\n';  // garbage value at second index
    cout << A[3]<<" "<<'\n';  // garbage value at third index
    cout << A[4]<<" "<<'\n';  // garbage value at fourth/last index
    return 0;
}
Declaring an array

Array initialization

To initialize the array above, we can write the values we want to assign inside the curly braces like this:

 int A[4] = {2, 8, 9, 1};

We’ve initialized with values 2, 8, 9, and 1, respectively so that A[0] will access the memory of 2, A[1] will access the memory of 8, and so on.

Look at the animation below to see how by using A[i] (where i is equal to the index of the array element), we can access each element of the array.

Understand the following code and its animation:

Press + to interact
int A[4] = {2, 8, 9, 1};
for(int i=0; i<4; i++)
{
int element = A[i];
}

In case we add the curly braces without writing any values inside them, then all values are initialized to zero.

 int A[5] = {};

Run the code below to see for yourself:

#include <iostream>
using namespace std;

int main()
{
    int A[5]={}; // All the values initialized to 0
    
    for(int i=0; i<5; i++)
        cout <<"Address of index "<<i<<" is "<<A+i<<": and value is "<< A[i]<<"\n";
    return 0;
}
Initializing an array (all elements initialized with 0s)

Note that whenever we write cout<<arrayName, it prints the base address (from where the array is starting) of the array. Similarly, arrayName+i will print the ith location (address) of the array. Similarly, arrayName[i] will access the value of the ith location of the array.

Let us have a small quiz.

Q

Given the code below, what do you think would be printed?

#include <iostream>
using namespace std;

int main()
{
    int A[5]={1,2};
    
    for(int i=0; i<4; i++)
        cout << A[i]<<"\n";
    return 0;
}
A)

Nothing will be printed as there is a logical error.

B)

1, 2, and 3 garbage values will be printed.

C)

1, 2, and 0 will be printed.

In reference to the quiz above, our array would be initialized like in the image below.

Below is the complete program where we declare and initialize the array and print its elements.

Click “Run” to execute the code below.

Run the code step by step to see how arrays first get declared, initialized (on the side panel under local variables, click “+ A”), and then printed.

#include <iostream>
using namespace std;

int main()
{
    int A[5] = {10,20,30,40,50};
    //A[0] = 10, A[1] = 20, A[2] = 30, A[3] = 40, A[4] = 50
    
    // printing the values stored inside the array
    cout << A[0]<<'\n';  // value at zeroth index
    cout << A[1]<<'\n';  // value at first index
    cout << A[2]<<'\n';  // value at second index
    cout << A[3]<<'\n';  // value at third index
    cout << A[4]<<'\n';  // value at fourth/last index
    return 0;
}
Array declaration and initialization

Printing addresses and accessing values of the array

We’ve seen how we can access the elements of an array. What if we had to print the addresses of each element of the array?

We can access the address of each element of an array by

We can access the address of each element of an array by using the address operator &. Or, we can perform simple arithmetic on the base address of the array by adding the offset (index) to the base address of the array.

In the animation below, we print the address using the latter method.

Now click “Run” to execute the code below. Here, we print both the element addresses and the array elements.

#include <iostream>
using namespace std;

int main()
{
    int A[5]={1,2,3,4,5};   
    // A[0] = 1, A[1] = 2, A[2] = 3, A[3] = 4, A[4] = 5
    
    // printing the addresses along with the values stored 
    //   on each index in the array (address: value)
    cout << "Printing the addresses using arithmetic: " << "\n";
    cout <<A+0<<": "<< A[0]<<'\n';
    cout <<A+1<<": "<< A[1]<<'\n';
    cout <<A+2<<": "<< A[2]<<'\n';
    cout <<A+3<<": "<< A[3]<<'\n';
    cout <<A+4<<": "<< A[4]<<'\n';

    cout << "Printing the addresses using &: " << "\n";
    cout <<&A[0]<<": "<< A[0]<<'\n';
    cout <<&A[1]<<": "<< A[1]<<'\n';
    cout <<&A[2]<<": "<< A[2]<<'\n';
    cout <<&A[3]<<": "<< A[3]<<'\n';
    cout <<&A[4]<<": "<< A[4]<<'\n';

    cout << " A: \t" << A << '\n';
    cout << "&A: \t" << &A << '\n';
    cout << "&A[0] \t" << &A[0] << '\n';

    return 0;
}
Printing addresses and the values stored on each index in the array

In the program above, after initializing the array, we print the address of the zeroth index followed by the value stored on the zeroth index in line 12 and likewise for all the other elements.

We’re adding the index number (offset) in the address to get each address. Since the data type of elements is int, each hexadecimal address of the next element is obtained by adding four bytes to the previous hexadecimal address.

So, we’re printing the address of the third value in the array by adding two to the base address (A + 2) of the array.

We’ve printed the addresses using the ampersand operator to access the address of each element (lines 19–23).

The address of the array &A is the same as the address of the first element of the array &A[0], which is the same as A.

Printing addresses and elements using a loop

We can print the addresses and values the same way as above using a loop as well as shown in the program below:

#include <iostream>
using namespace std;

int main()
{
	int A[5] = { 1, 2, 3, 4, 5 };

	// Printing addresses and values using loop
	for (int i = 0; i < 5; i++)
		cout << A + i << ": " << "A[" << i << "]: " << A[i] << endl;

	return 0;
}
Accessing array elements using loop

Array elements as references

Look at the following code and see the output:

#include <iostream>
using namespace std;
int main()
{
int A[] = { 1, 2, 3, 4, 5
}, size = 5;
for (int i = 0; i < size; i++)
{
int &ref = A[i]; // every time ref will be pointing to a different
ref++; // element of the array.
}
for (int i = 0; i < size; i++)
cout << A[i] << " ";
return 0;
}
Reference of an array element

Every time int& ref=A[i] will be a different memory reference. So, in each iteration, the increment in ref will increment the element of the array.