Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Declaring arrays in C++

I am new to C++ and currently learning it with a book by myself. This book seems to say that there are several kinds of arrays depending on how you declare it. I guess the difference between dynamic arrays and static arrays are clear to me. But I do not understand the difference between the STL std::array class and a static array.

An STL std::array variable is declared as:

std::array < int, arraySize > array1;

Whereas a static array variable is declared as:

int array1[arraySize];

Is there a fundamental difference between the two? Or is it just syntax and the two are basically the same?

like image 977
Astaboom Avatar asked Nov 23 '16 20:11

Astaboom


People also ask

How do you declare an array in C?

To create an array, define the data type (like int ) and specify the name of the array followed by square brackets []. To insert values to it, use a comma-separated list, inside curly braces: int myNumbers[] = {25, 50, 75, 100}; We have now created a variable that holds an array of four integers.

What is declaring an array?

An "array declaration" names the array and specifies the type of its elements. It can also define the number of elements in the array. A variable with array type is considered a pointer to the type of the array elements.

What is array in C explain with example?

An array is a variable that can store multiple values. For example, if you want to store 100 integers, you can create an array for it. int data[100];


2 Answers

A std::array<> is just a light wrapper around a C-style array, with some additional nice interface member functions (like begin, end etc) and typedefs, roughly defined as

template<typename T, size_t N>
class array
{
public:
    T _arr[N];
    T& operator[](size_t);
    const T& operator[](size_t) const;
    // other member functions and typedefs
}

One fundamental difference though is that the former can be passed by value, whereas for the latter you only pass a pointer to its first element or you can pass it by reference, but you cannot copy it into the function (except via a std::copy or manually).

A common mistake is to assume that every time you pass a C-style array to a function you lose its size due to the array decaying to a pointer. This is not always true. If you pass it by reference, you can recover its size, as there is no decay in this case:

#include <iostream>

template<typename T, size_t N>
void f(T (&arr)[N]) // the type of arr is T(&)[N], not T*
{
    std::cout << "I'm an array of size " << N;
}

int main()
{
    int arr[10];
    f(arr); // outputs its size, there is no decay happening
}

Live on Coliru

like image 164
vsoftco Avatar answered Oct 05 '22 20:10

vsoftco


The main difference between these two is an important one.

Besides the nice methods the STL gives you, when passing a std::array to a function, there is no decay. Meaning, when you receive the std::array in the function, it is still a std::array, but when you pass an int[] array to a function, it effectively decays to an int* pointer and the size of the array is lost.

This difference is a major one. Once you lose the array size, the code is now prone to a lot of bugs, as you have to keep track of the array size manually. sizeof() returns the size of a pointer type instead of the number of elements in the array. This forces you to manually keep track of the array size using interfaces like process(int *array, int size). This is an ok solution, but prone to errors.

See the guidelines by Bjarne Stroustroup:

https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#Rp-run-time

That can be avoided with a better data type, which std::array is designed for, among many other STL classes.

As a side note, unless there's a strong reason to use a fixed size array, std::vector may be a better choice as a contiguous memory data structure.

like image 28
Steve Thibault Avatar answered Oct 05 '22 19:10

Steve Thibault