Let's say I have these 10 previously declared arrays in my code.
int arr1[] = {1,2,3,4,5,6,7,8,9,10};
int arr2[] = {1,2,3,4,5,6,7,8,9,10};
int arr3[] = {1,2,3,4,5,6,7,8,9,10};
int arr4[] = {1,2,3,4,5,6,7,8,9,10};
int arr5[] = {1,2,3,4,5,6,7,8,9,10};
int arr6[] = {1,2,3,4,5,6,7,8,9,10};
int arr7[] = {1,2,3,4,5,6,7,8,9,10};
int arr8[] = {1,2,3,4,5,6,7,8,9,10};
int arr9[] = {1,2,3,4,5,6,7,8,9,10};
int arr10[] = {1,2,3,4,5,6,7,8,9,10};
Basically, I want to append all 10 of these arrays one after another to make one single array.
ArrayOfArrays = { arr1[], arr2[], arr3[], arr4[], arr5[], arr6[], arr7[], arr8[], arr9[], arr10[] }
How would I go about doing this? This question might seem trivial for some, but I'm new to C++ and can not figure out how to do it. Please help and thanks in advance.
Basically, I want to append all 10 of these arrays one after another to make one single array.
You cannot do that.
The closest you can get to that is by using std::array.
std::array<int, 10> arr1 = {1,2,3,4,5,6,7,8,9,10};
...
std::array<int, 10> arr10 = {1,2,3,4,5,6,7,8,9,10};
std::array<std::array<int, 10>, 10> arrayOfArray = {arr1, ..., arr10};
Try this approach:
#include <iostream>
#include <vector>
int arr1[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int arr2[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
// ...other arrays here...
// We pass a reference to a vector and return the same vector for performance reasons.
// Compiler often can optimize that into a better code.
std::vector<int> append(std::vector<int> & vec, int * data, int size)
{
for (int i = 0; i < size; ++i)
vec.push_back(data[i]);
return vec;
}
int main()
{
std::vector<int> data;
data = append(data, arr1, 10);
data = append(data, arr2, 10);
for (auto i : data)
std::cout << i << ", ";
std::cout << std::endl;
return 0;
}
Also, in C++ there are good containers for storing arrays, try searching for std::array and std::vector containers. First is a fixed size static array, the other one is dynamic.
I want to append all 10 of these arrays one after another to make one
single array ?
You can have array of pointers like
int *ArrayOfPointers[10] = { &arr1, &arr2, &arr3, &arr4, &arr5, &arr6, &arr7, &arr8, &arr9, &arr10};
Here ArrayOfPointers is array of 10 int pointers i.e it can store address of 10 one dimension int array like arr1, arr2 etc.
I assume there may be better method than what I'm suggesting in advance C++ for the same task.
In C++ it is unnecessary and ill-advised to use C-style arrays. For arrays of
constant size you may use std::array
and for arrays of variable size, std::vector
It looks rather as if what you actually want is a constant two-dimensional matrix
and to be able to access each of its rows as as a constant array, but do not
know how to initialise a two-dimensional matrix. If that's the case, here's how:
#include <iostream>
#include <array>
std::array<std::array<int,10>,10> matrix = {{
{{1,2,3,4,5,6,7,8,9,10}},
{{1,2,3,4,5,6,7,8,9,10}},
{{1,2,3,4,5,6,7,8,9,10}},
{{1,2,3,4,5,6,7,8,9,10}},
{{1,2,3,4,5,6,7,8,9,10}},
{{1,2,3,4,5,6,7,8,9,10}},
{{1,2,3,4,5,6,7,8,9,10}},
{{1,2,3,4,5,6,7,8,9,10}},
{{1,2,3,4,5,6,7,8,9,10}},
{{1,2,3,4,5,6,7,8,9,10}}
}};
int main()
{
std::array<int,10> const & arr0 = matrix[0];
for (int const & i : arr0) {
std::cout << i << ' ';
}
std::cout << std::endl;
// Or more simply...
auto const & arr5 = matrix[5];
for (auto const & i : arr5) {
std::cout << i << ' ';
}
std::cout << std::endl;
}
Compile, link and run:
$ g++ -Wall -Wextra main.cpp && ./a.out
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
live demo
I am a beginner in c++ and I am trying to understand vectors.
I know the basic format which is:
vector <dataType> vectorName;
People are telling me that vectors are like arrays. But, what I don't
understand is that for arrays you can do this:
array[] = {1, 2, 3}
But for vectors you don't seem to get to set it to a list. Or do you have
to keep using .push_back().
Also, can you use something like vectorName[1] or not?
Can anyone explain this to me?
Thanks.
You can use the style if you use C++11 or later.
#include <iostream>
#include <vector>
int main(void) {
std::vector<int> vec = {1, 2, 3};
std::cout << vec[1] << std::endl;
return 0;
}
The whole purpose of vectors is to be "infinite", so you don't have to redefine it everytime you need to expand it.
push_back is made so you can add/expand to the array without redefining it; you still access and modify like a normal array:
std::vector<int> a;
a.push_back(2);
a.push_back(6);
std::cout << a[0] << std::end; //2
std::cout << a[1] << std::end; //6
a[0] = 5;
a[1] = 7;
std::cout << a[0] << std::end; //5
std::cout << a[1] << std::end; //7
You can also initialize it old-school style (the = is optional):
std::vector<int> a {2, 6};
std::cout << a[0] << std::end; //2
std::cout << a[1] << std::end; //6
Try this for C++:
#include <iostream>
#include <vector>
int main(void) {
std::vector<int> vec { 34,23 };
return 0;
}
Or even:
#include <iostream>
#include <vector>
int main(void) {
std::vector<int> v(2);
v = { 34,23 };
return 0;
}
seems non of the above gave you any hint on dealing with the vector after you created it, so, let's say you created it with few initial values.
#include <iostream>
#include <vector>
int main(void) {
std::vector<int> vec { 34,23 };
// use push_back(some_value) if you have multiple values to put inside, say 1000.
// instead of using the index [] brackets, try .at() method
std::cout << vec.at(1) << std::endl;
// use both the .size() or the new syntax to loop over it
for (unsigned i = 0 ; i < vec.size() ; i++){
std::cout << vec.at(i) << std::endl;
}
// or the new syntax
for (auto & i : vec){
std::cout << i << std::endl;
}
return 0;
}
Have fun :)
Vectors are expandable arrays. Unlike an array, you are not restricted to the size you initialized it with.
Growth of vector: the vector doubles it size whenever you overflow it. Underneath the hood its still an array but the "expandable" property of it comes by copying the contents of the previous array into a new larger array.
Few things that you can do with vectors in C++
Initialization of vector
vector<Type> one (size, defaultValue);
vector<Type> two (one); // makes a new vector *two* with the contents of *one*
vector<int> three {1,2,3}; // using initializer list
Accessing an element
int temp = three[2]; //array like syntax
int temp = three.at(2);
You cannot increase the size of a vector using this syntax i.e. you cannot dothree[3]=4;
Expanding
three.pusk_back(4);
Shrinking
three.pop_back();
I am trying to copy a vector into an array however I don't know how to declare the array from the size of the vector.
Code:
int main() {
vector<int> ivec = {1, 2, 3, 4, 5};
constexpr size_t size = ivec.size();
int arr[size];
for(size_t i = 0; i < ivec.size(); ++i)
arr[i] = ivec[i];
for(size_t i : arr)
cout << i << endl;
return 0;
}
However, I think this won't compile because ivec.size() can't be a constant expression (though I'm not sure if this is the case). In which case how could I do this without having to manually enter the number of elements?
As of right now std::vector size() is not a constexpr, so you cannot use it in constexpressions. As a result, you can try using the new keyword for dynamically sized arrays, but that would be pointless, as you're already using a vector.
vector<int> vi = {1, 2, 3, 4, 5};
int* arr = new int[vi.size()];
std::copy(vi.begin(), vi.end(), arr);
for (unsigned int i = 0; i < vi.size(); i++)
std::cout << arr[i] << " ";
delete[] arr;
Note:: You can use std::begin() with the second example because arr[] is an array but not with the first example because arr* is a pointer. However, std::copy() accepts both, so it should be fine.
initializer_lists can be used in constexpressions:
constexpr initializer_list<int> il = {1, 2, 3, 4, 5};
int arr[il.size()];
std::copy(il.begin(), il.end(), std::begin(arr));
for (unsigned int i = 0; i < il.size(); i++)
std::cout << arr[i] << " ";
In general, it is not possible to copy a vector into array, because, a usual array is constexpr, while vector size is not, it is of dynamic size. There are also dynamic arrays supported by some compilers, but then again, there size is never constexpr.
I guess, you need just to use vector.
I don't know your motivation, but...
int main() {
vector<int> ivec = {1, 2, 3, 4, 5};
constexpr size_t size = ivec.size();
int* arr = (int*)malloc( sizeof( int * size ) );
for(size_t i = 0; i < ivec.size(); ++i)
arr[i] = ivec[i];
for(size_t i : arr)
cout << i << endl;
free( arr );
return 0;
}
You need to allocate memory, because as you have said vector size is not a constant:
int main() {
vector<int> ivec = { 1, 2, 3, 4, 5 };
size_t size = ivec.size();
int *arr = new int[size]; // allocate memory
for (size_t i = 0; i < ivec.size(); ++i)
arr[i] = ivec[i];
for (size_t i = 0; i < size; ++i)
cout << i << endl;
delete [] arr; // release memory
return 0;
}
It seems you want to get hold of the number of the elements in an initializer list yielding a constexpr. The only way I'm aware of doing this is to use
#include <cstddef>
template <typename T, std::size_t N>
constexpr std::size_t size(T(&)[N]) {
return N;
}
int main() {
int vec[] = { 1, 2, 3, 4, 5 };
constexpr std::size_t s = size(vec);
int array[s];
std::copy(std::begin(vec), std::end(vec), array);
}
If you really need to use a std::vector<T> as source, you'll need to allocate memory, probably using std::vector<T> in the first place! If you want to allocate the memory yourself you'd use it something like this:
std::vector<int> vec = { 1, 2, 3, 4, 5 };
std::unique_ptr<int[]> array(new int[vec.size()]);
std::copy(vec.begin(), vec.end(), array.get());
The use of std::unique_ptr<int[]> makes sure that the allocated memory is released automatically.
A constexpr is a Constant Expression which is an expression that is evaluated at compile-time. That it is known at compile-time is a fundamental trait of a constexpr.
Given this, you can see how it makes no sense to try to construct a non-dynamically-allocated C-style array at run time when the number of elements will only be known at run-time. The two ideas are orthogonal.
From a technical standpoint, you cannot initialize a constexpr from a non-constant-expression. vector::size() is non-constexpr, so as you suspect, it is not only not compilable, but it is also not logical from a design standpoint to try to construct a constexpr from it:
constexpr size_t size = ivec.size(); // NO GOOD!
All this being said, it's very rare to need to construct a C-style array from vector. You're already doing the Right Thing by using vector in the first place. Don't mess it all up now by copying it to a crappy array.
A vector is guaranteed to have contigious storage. What this means is you can use it just like a C-style array in most cases. All you need to do is pass the address (or reference) to the first element in the vector to whatever is expecting a C-style array and it will work just fine.
void AincentApiFunction (int* array, size_t sizeofArray);
int main()
{
std::vector <int> v;
// ...
AincentApiFunction (&v[0], v.size());
}
I'd avoid
constexpr size_t size = ivec.size();
int arr[size];
and do it like this
size_t size = ivec.size();
int* arr = new int[size];
and then you handle it like the constantly allocated array. Read more about dynamically allocated arrays.
and don't forget to
delete[] array;
In C++11 arrays may declared as runtime bound on the stack:
(Note: this is only per the latest available draft: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3690.pdf and will likely not be standard, but g++ with -std=c++11 will allow it
Note that is is not constexpression:
8.3.4 Arrays [dcl.array]
D1 [ expressionopt] attribute-specifier-seqopt
Example from the standard:
void f(unsigned int n) {
int a[n]; // type of a is “array of runtime bound of int”
}
So all you need to do is remove constexpr:
int main() {
vector<int> ivec = {1, 2, 3, 4, 5};
size_t size = ivec.size(); // this is fine
int arr[size];
for(size_t i = 0; i < ivec.size(); ++i)
arr[i] = ivec[i];
for(size_t i : arr)
cout << i << endl;
return 0;
}
Your compiler may or may not allow this, so depends on how strictly standard you need to be