-->
Conceptual layout of a multi-dimensional arrayAn array is a series of elements of the same type placed in contiguous memory locations that can be individually referenced by adding an index to a unique identifier.
That means that, for example, five values of type
For example, an array containing 5 integer values of type
where each blank panel represents an element of the array. In this case, these are values of type
Like a regular variable, an array must be declared before it is used. A typical declaration for an array in C++ is:
where
Therefore, the
NOTE: The
But the elements in an array can be explicitly initialized to specific values when it is declared, by enclosing those initial values in braces {}. For example:
This statement declares an array that can be represented like this:
The number of values between braces
Will create an array like this:
The initializer can even have no values, just the braces:
This creates an array of five
When an initialization of values is provided for an array, C++ allows the possibility of leaving the square brackets empty
After this declaration, array
Finally, the evolution of C++ has led to the adoption of universal initialization also for arrays. Therefore, there is no longer need for the equal sign between the declaration and the initializer. Both these statements are equivalent:
Static arrays, and those declared directly in a namespace (outside any function), are always initialized. If no explicit initializer is specified, all the elements are default-initialized (with zeroes, for fundamental types).
Following the previous examples in which
For example, the following statement stores the value 75 in the third element of
and, for example, the following copies the value of the third element of
Therefore, the expression
Notice that the third element of
In C++, it is syntactically correct to exceed the valid range of indices for an array. This can create problems, since accessing out-of-range elements do not cause errors on compilation, but can cause errors on runtime. The reason for this being allowed will be seen in a later chapter when pointers are introduced.
At this point, it is important to be able to clearly distinguish between the two uses that brackets
The main difference is that the declaration is preceded by the type of the elements, while the access is not.
Some other valid operations with arrays:
For example:
and, for example, the way to reference the second element vertically and fourth horizontally in an expression would be:
(remember that array indices always begin with zero).
Multidimensional arrays are not limited to two indices (i.e., two dimensions). They can contain as many indices as needed. Although be careful: the amount of memory needed for an array increases exponentially with each dimension. For example:
At the end, multidimensional arrays are just an abstraction for programmers, since the same results can be achieved with a simple array, by multiplying its indices:
With the only difference that with multidimensional arrays, the compiler automatically remembers the depth of each imaginary dimension. The following two pieces of code produce the exact same result, but one uses a bidimensional array while the other uses a simple array:
None of the two code snippets above produce any output on the screen, but both assign values to the memory block called jimmy in the following way:
Note that the code uses defined constants for the width and height, instead of using directly their numerical values. This gives the code a better readability, and allows changes in the code to be made easily in one place.
To accept an array as parameter for a function, the parameters can be declared as the array type, but with empty brackets, omitting the actual size of the array. For example:
This function accepts a parameter of type 'array of
it would be enough to write a call like this:
Here you have a complete example:
In the code above, the first parameter (
In a function declaration, it is also possible to include multidimensional arrays. The format for a tridimensional array parameter is:
For example, a function with a multidimensional array as argument could be:
Notice that the first brackets
In a way, passing an array as argument always loses a dimension. The reason behind is that, for historical reasons, arrays cannot be directly copied, and thus what is really passed is a pointer. This is a common source of errors for novice programmers. Although a clear understanding of pointers, explained in a coming chapter, helps a lot.
To overcome some of these issues with language built-in arrays, C++ provides an alternative array type as a standard container. It is a type template (a class template, in fact) defined in header
Containers are a library feature that falls out of the scope of this tutorial, and thus the class will not be explained in detail here. Suffice it to say that they operate in a similar way to built-in arrays, except that they allow being copied (an actually expensive operation that copies the entire block of memory, and thus to use with care) and decay into pointers only when explicitly told to do so (by means of its member
Just as an example, these are two versions of the same example using the language built-in array described in this chapter, and the container in the library:
As you can see, both kinds of arrays use the same syntax to access its elements:
- Multidimensional Array In Dev C++
- Creating Array In Dev C++
- Array C++ Code
- C++ Array In Class
- Array In C++ Example
Nov 14, 2019 In a C array declaration, the array size is specified after the variable name, not after the type name as in some other languages. The following example declares an array of 1000 doubles to be allocated on the stack.
An array is a sequence of objects of the same type that occupy a contiguous area of memory. Traditional C-style arrays are the source of many bugs, but are still common, especially in older code bases. In modern C++, we strongly recommend using std::vector or std::array instead of C-style arrays described in this section. Both of these standard library types store their elements as a contiguous block of memory but provide much greater type safety along with iterators that are guaranteed to point to a valid location within the sequence. For more information, see Containers (Modern C++).
Stack declarations
In a C++ array declaration, the array size is specified after the variable name, not after the type name as in some other languages. The following example declares an array of 1000 doubles to be allocated on the stack. The number of elements must be supplied as an integer literal or else as a constant expression because the compiler has to know how much stack space to allocate; it cannot use a value computed at run-time. Each element in the array is assigned a default value of 0. If you do not assign a default value, each element will initially contain whatever random values happen to be at that location.
The first element in the array is the 0th element, and the last element is the (n-1) element, where n is the number of elements the array can contain. The number of elements in the declaration must be of an integral type and must be greater than 0. It is your responsibility to ensure that your program never passes a value to the subscript operator that is greater than
(size - 1)
.A zero-sized array is legal only when the array is the last field in a struct or union and when the Microsoft extensions (/Ze) are enabled.
Stack-based arrays are faster to allocate and access than heap-based arrays, but the number of elements can't be so large that it uses up too much stack memory. How much is too much depends on your program. You can use profiling tools to determine whether an array is too large.
Heap declarations
If you require an array that is too large to be allocated on the stack, or whose size cannot be known at compile time, you can allocate it on the heap with a new[] expression. The operator returns a pointer to the first element. You can use the subscript operator with the pointer variable just as with a stack-based array. You can also use pointer arithmetic to move the pointer to any arbitrary elements in the array. It is your responsibility to ensure that:
- you always keep a copy of the original pointer address so that you can delete the memory when you no longer need the array.
- you do not increment or decrement the pointer address past the array bounds.
The following example shows how to define an array on the heap at run time, and how to access the array elements using the subscript operator or by using pointer arithmetic:
Initializing arrays
You can initialize an array in a loop, one element at a time, or in a single statement. The contents of the following two arrays are identical:
Passing arrays to functions
When an array is passed to a function, it is passed as a pointer to the first element. This is true for both stack-based and heap-based arrays. The pointer contains no additional size or type information. This behavior is called pointer decay. When you pass an array to a function, you must always specify the number of elements in a separate parameter. This behavior also implies that the array elements are not copied when the array is passed to a function. To prevent the function from modifying the elements, specify the parameter as a pointer to const elements.
The following example shows a function that accepts an array and a length. The pointer points to the original array, not a copy. Because the parameter is not const, the function can modify the array elements.
Declare the array as const to make it read-only within the function block:
The same function can also be declared in these ways, with no change in behavior. The array is still passed as a pointer to the first element:
Multidimensional arrays
Arrays constructed from other arrays are multidimensional arrays. These multidimensional arrays are specified by placing multiple bracketed constant expressions in sequence. For example, consider this declaration:
It specifies an array of type int, conceptually arranged in a two-dimensional matrix of five rows and seven columns, as shown in the following figure:
Conceptual layout of a multi-dimensional array
In declarations of multidimensioned arrays that have an initializer list (as described in Initializers), the constant expression that specifies the bounds for the first dimension can be omitted. For example:
The preceding declaration defines an array that is three rows by four columns. The rows represent factories and the columns represent markets to which the factories ship. The values are the transportation costs from the factories to the markets. The first dimension of the array is left out, but the compiler fills it in by examining the initializer.
Use of the indirection operator (*) on an n-dimensional array type yields an n-1 dimensional array. If n is 1, a scalar (or array element) is yielded.
C++ arrays are stored in row-major order. Row-major order means the last subscript varies the fastest.
Example
The technique of omitting the bounds specification for the first dimension of a multidimensional array can also be used in function declarations as follows:
The function
FindMinToMkt
is written such that adding new factories does not require any code changes, just a recompilation.Initializing Arrays
If a class has a constructor, arrays of that class are initialized by a constructor. If there are fewer items in the initializer list than elements in the array, the default constructor is used for the remaining elements. If no default constructor is defined for the class, the initializer list must be complete — that is, there must be one initializer for each element in the array.
Consider the
Point
class that defines two constructors:The first element of
aPoint
is constructed using the constructor Point( int, int )
; the remaining two elements are constructed using the default constructor.Static member arrays (whether const or not) can be initialized in their definitions (outside the class declaration). For example:
Accessing array elements
You can access individual elements of an array by using the array subscript operator (
[ ]
). If a one-dimensional array is used in an expression that has no subscript, the array name evaluates to a pointer to the first element in the array.When you use multidimensional arrays, you can use various combinations in expressions.
In the preceding code,
multi
is a three-dimensional array of type double. The p2multi
pointer points to an array of type double of size three. In this example, the array is used with one, two, and three subscripts. Although it is more common to specify all subscripts, as in the cout
statement, it is sometimes useful to select a specific subset of array elements, as shown in the statements that follow cout
.Overloading subscript operator
Multidimensional Array In Dev C++
Like other operators, the subscript operator (
[]
) can be redefined by the user. The default behavior of the subscript operator, if not overloaded, is to combine the array name and the subscript using the following method:*((array_name) + (subscript))
As in all addition that involves pointer types, scaling is performed automatically to adjust for the size of the type. Therefore, the resultant value is not n bytes from the origin of array-name; rather, it is the nth element of the array. For more information about this conversion, see Additive operators.
Similarly, for multidimensional arrays, the address is derived using the following method:
((array_name) + (subscript1 * max2 * max3 * ... * maxn) + (subscript2 * max3 * ... * maxn) + ... + subscriptn))
Arrays in Expressions
When an identifier of an array type appears in an expression other than
sizeof
, address-of (&
), or initialization of a reference, it is converted to a pointer to the first array element. For example:The pointer
psz
points to the first element of the array szError1
. Arrays, unlike pointers, are not modifiable l-values. Therefore, the following assignment is illegal:See also
That means that, for example, five values of type
int
can be declared as an array without having to declare 5 different variables (each with its own identifier). Instead, using an array, the five int
values are stored in contiguous memory locations, and all five can be accessed using the same identifier, with the proper index.For example, an array containing 5 integer values of type
int
called foo
could be represented as:where each blank panel represents an element of the array. In this case, these are values of type
int
. These elements are numbered from 0 to 4, being 0 the first and 4 the last; In C++, the first element in an array is always numbered with a zero (not a one), no matter its length.Like a regular variable, an array must be declared before it is used. A typical declaration for an array in C++ is:
type name [elements];
where
type
is a valid type (such as int
, float
...), name
is a valid identifier and the elements
field (which is always enclosed in square brackets []
), specifies the length of the array in terms of the number of elements.Therefore, the
foo
array, with five elements of type int
, can be declared as:NOTE: The
elements
field within square brackets []
, representing the number of elements in the array, must be a constant expression, since arrays are blocks of static memory whose size must be determined at compile time, before the program runs.Initializing arrays
By default, regular arrays of local scope (for example, those declared within a function) are left uninitialized. This means that none of its elements are set to any particular value; their contents are undetermined at the point the array is declared.But the elements in an array can be explicitly initialized to specific values when it is declared, by enclosing those initial values in braces {}. For example:
This statement declares an array that can be represented like this:
The number of values between braces
{}
shall not be greater than the number of elements in the array. For example, in the example above, foo
was declared having 5 elements (as specified by the number enclosed in square brackets, []
), and the braces {}
contained exactly 5 values, one for each element. If declared with less, the remaining elements are set to their default values (which for fundamental types, means they are filled with zeroes). For example:Will create an array like this:
The initializer can even have no values, just the braces:
This creates an array of five
int
values, each initialized with a value of zero:When an initialization of values is provided for an array, C++ allows the possibility of leaving the square brackets empty
[]
. In this case, the compiler will assume automatically a size for the array that matches the number of values included between the braces {}
:After this declaration, array
foo
would be 5 int
long, since we have provided 5 initialization values.Finally, the evolution of C++ has led to the adoption of universal initialization also for arrays. Therefore, there is no longer need for the equal sign between the declaration and the initializer. Both these statements are equivalent:
Static arrays, and those declared directly in a namespace (outside any function), are always initialized. If no explicit initializer is specified, all the elements are default-initialized (with zeroes, for fundamental types).
Accessing the values of an array
The values of any of the elements in an array can be accessed just like the value of a regular variable of the same type. The syntax is:name[index]
Following the previous examples in which
foo
had 5 elements and each of those elements was of type int
, the name which can be used to refer to each element is the following:For example, the following statement stores the value 75 in the third element of
foo
:and, for example, the following copies the value of the third element of
foo
to a variable called x
:Therefore, the expression
foo[2]
is itself a variable of type int
.Notice that the third element of
foo
is specified foo[2]
, since the first one is foo[0]
, the second one is foo[1]
, and therefore, the third one is foo[2]
. By this same reason, its last element is foo[4]
. Therefore, if we write foo[5]
, we would be accessing the sixth element of foo
, and therefore actually exceeding the size of the array.In C++, it is syntactically correct to exceed the valid range of indices for an array. This can create problems, since accessing out-of-range elements do not cause errors on compilation, but can cause errors on runtime. The reason for this being allowed will be seen in a later chapter when pointers are introduced.
At this point, it is important to be able to clearly distinguish between the two uses that brackets
[]
have related to arrays. They perform two different tasks: one is to specify the size of arrays when they are declared; and the second one is to specify indices for concrete array elements when they are accessed. Do not confuse these two possible uses of brackets []
with arrays.The main difference is that the declaration is preceded by the type of the elements, while the access is not.
Some other valid operations with arrays:
For example:
Multidimensional arrays
Multidimensional arrays can be described as 'arrays of arrays'. For example, a bidimensional array can be imagined as a two-dimensional table made of elements, all of them of a same uniform data type.jimmy
represents a bidimensional array of 3 per 5 elements of type int
. The C++ syntax for this is:and, for example, the way to reference the second element vertically and fourth horizontally in an expression would be:
(remember that array indices always begin with zero).
Multidimensional arrays are not limited to two indices (i.e., two dimensions). They can contain as many indices as needed. Although be careful: the amount of memory needed for an array increases exponentially with each dimension. For example:
declares an array with an element of type
char
for each second in a century. This amounts to more than 3 billion char
! So this declaration would consume more than 3 gigabytes of memory!At the end, multidimensional arrays are just an abstraction for programmers, since the same results can be achieved with a simple array, by multiplying its indices:
With the only difference that with multidimensional arrays, the compiler automatically remembers the depth of each imaginary dimension. The following two pieces of code produce the exact same result, but one uses a bidimensional array while the other uses a simple array:
multidimensional array | pseudo-multidimensional array |
---|
None of the two code snippets above produce any output on the screen, but both assign values to the memory block called jimmy in the following way:
Note that the code uses defined constants for the width and height, instead of using directly their numerical values. This gives the code a better readability, and allows changes in the code to be made easily in one place.
Arrays as parameters
At some point, we may need to pass an array to a function as a parameter. In C++, it is not possible to pass the entire block of memory represented by an array to a function directly as an argument. But what can be passed instead is its address. In practice, this has almost the same effect, and it is a much faster and more efficient operation.To accept an array as parameter for a function, the parameters can be declared as the array type, but with empty brackets, omitting the actual size of the array. For example:
This function accepts a parameter of type 'array of
int
' called arg
. In order to pass to this function an array declared as:it would be enough to write a call like this:
Here you have a complete example:
In the code above, the first parameter (
int arg[]
) accepts any array whose elements are of type int
, whatever its length. For that reason, we have included a second parameter that tells the function the length of each array that we pass to it as its first parameter. This allows the for loop that prints out the array to know the range to iterate in the array passed, without going out of range.In a function declaration, it is also possible to include multidimensional arrays. The format for a tridimensional array parameter is:
For example, a function with a multidimensional array as argument could be:
Notice that the first brackets
[]
are left empty, while the following ones specify sizes for their respective dimensions. This is necessary in order for the compiler to be able to determine the depth of each additional dimension.In a way, passing an array as argument always loses a dimension. The reason behind is that, for historical reasons, arrays cannot be directly copied, and thus what is really passed is a pointer. This is a common source of errors for novice programmers. Although a clear understanding of pointers, explained in a coming chapter, helps a lot.
Library arrays
The arrays explained above are directly implemented as a language feature, inherited from the C language. They are a great feature, but by restricting its copy and easily decay into pointers, they probably suffer from an excess of optimization.To overcome some of these issues with language built-in arrays, C++ provides an alternative array type as a standard container. It is a type template (a class template, in fact) defined in header
'><array>
Creating Array In Dev C++
.Containers are a library feature that falls out of the scope of this tutorial, and thus the class will not be explained in detail here. Suffice it to say that they operate in a similar way to built-in arrays, except that they allow being copied (an actually expensive operation that copies the entire block of memory, and thus to use with care) and decay into pointers only when explicitly told to do so (by means of its member
data
).Just as an example, these are two versions of the same example using the language built-in array described in this chapter, and the container in the library:
Array C++ Code
language built-in array | container library array |
---|
As you can see, both kinds of arrays use the same syntax to access its elements:
myarray[i]
. Other than that, the main differences lay on the declaration of the array, and the inclusion of an additional header for the library array. Notice also how it is easy to access the size of the library arrayC++ Array In Class
.Array In C++ Example
Previous: Name visibility | Index | Next: Character sequences |