Why do these loops give the same output:
#include<iostream>
#include<vector>
using namespace std;
int main()
{
vector<int> ar = {2, 3 ,4};
for(auto i: ar) //this line changes in the next loop
cout<<i<<" ";
cout<<"\n";
for(auto &i: ar) //i changed to &i
cout<<i<<" ";
}
They both give the same output:
2 3 4
2 3 4
When declaring the foreach loop variable, shouldn't adding ampersand make the variable take the references of the values in the array, and printing i make it print the references. What is happening here?
By print the references I meant something like this code prints:
for(auto i: ar)
cout<<&i<<" ";
Output:
0x61fdbc 0x61fdbc 0x61fdb
The results are the same because in the first loop you copy the variable's value in a new variable i and print its value. (Additional RAM allocated)
In the second loop you access the value of the current element from the memory by assigning its address to i. (No additional RAM allocated)
On the other side:
cout<<&i<<" ";
causes printing the address of i.
The ampersand operator has many purposes. These two of the many are hard to recognize, namely the & infront of a variable in a declaration ( such as int& i ( or int &i, same thing ) ), and the & infront of a variable not in a declaration, such as cout << &i.
Try these and you will get a better understanding.
for (auto i : ar)
cout << i << " "; // 2 3 4 // element of ar
for (auto &i : ar)
cout << i << " "; // 2 3 4 // element of ar
for (auto i : ar)
cout << &i << " "; // address of local variable i (probably same address)
for (auto &i: ar)
cout << &i << " "; // address of elements of ar (increasing addresses)
Related
This question already has answers here:
Why does auto works differently in "range for" in 2D and 1D arrays in C++
(4 answers)
Closed last month.
I was curious about why we go through a multidimensional array this way
for (auto& row : mat1)
{
for (int& elements : row)
{
cin >> elements;
}
}
Why do we use &(pass by ref) when we make a temp variable called elements that goes through the rows and gets each value. aswell as the & in the for (auto& row : mat1) Can someone explain this whole part with every detail please ?
using namespace std;
int main()
{
const int row{ 3 }, col{ 3 };
array<array<int, col>, row > mat1;
cout << "Enter matrix 1 elements: ";
for (auto& row : mat1)
{
for (int& elements : row)
{
cin >> elements;
}
}
for (auto& row : mat1)
{
for (int& elements : row)
cout << elements << " ";
cout << endl;
}
If you don't use references, then you will make copies of the data.
And if you make a copy (iterate by value) rather than using references, you will only modify the local copy, not the original data.
This is for the input loop of course, where you have
cin >> elements;
In the output loop there's no need for references for the int elements themselves, but I recommend using const references for the arrays since otherwise you make a copy which could be expensive.
So in the output loop to:
for (auto const& row : mat1)
{
for (auto element : row)
{
std::cout << element;
}
}
I'm new to C++ and wanted to make a small function today which would flip all the elements of an array that was given to it (I had a pretty good idea for it). I started using arrays, but ran into issues since only a pointer to the first element is passed to the function; it was giving some very strange output. It was recommended I use a vector instead, but that started to give me some really odd output, too. I added a cout iterating over the vector values to see what it contains for some sanity-checking, but the outputs are completely bizarre; looks like I'm struggling to work out how to read input into it correctly.
As I mentioned, I first tried an array, which I could read into fine with a range-for loop. I tried that same thing with vectors (solution 1) and found it to be ignoring the first input, and assigning each element the last value that I gave it.
I first tried other Stack overflow threads but I found the solutions far too verbose or not suitable for something as simple as I need.
I thought maybe the vector couldn't be used in the range-for so I did for(auto x : array_size) instead - this gave an error stating there was no suitable "begin" for the function, so I changed this back.
Instead I looked around at the documentation and found .push_back(value) (solution 2) which appeared to put a given value at the end of the vector. Thought I might at least get some input into it correctly, which would be a step in the right direction. Instead, the output seems to show it doubled the number of positions in the vector and just assigned my first input to the furthest position. I imagine this is due to me specifying a size for the vector, and then having push_back grow the vector by that number of inputs (resulting in a double-size vector).
As for the input values themselves, I'm stumped.
Below is the offending bit of code as it stands with solution 2.
int main()
{
int array_size;
auto index_num = 0;
int arr_input = 0;
std::cout << "This program flips an array." << "\n";
std::cout << "Enter how many elements will be in your array: ";
std::cin >> array_size;
std::vector<int> user_array (array_size);
std::cout << "Fill your array with integer values. Press 'Enter' after each: " << std::endl;
for(auto x : user_array)
{
std::cin >> arr_input;
user_array.push_back(arr_input);
}
index_num = sizeof(user_array) / sizeof(user_array[0]); //or just use array_size-1 instead?
std::cout << "Your array, unflipped, contains the values: " << "\n";
for(auto y : user_array)
{
std::cout << "[" << user_array[y] << "] ";
}
Solution 2 provides this output:
Fill your array with integer values. Press 'Enter' after each:
1
2
3
4
5
Your array, unflipped, contains the values:
[0] [0] [0] [0] [0] [0] [0] [0] [0] [1]
Solution 1, where I attempt to input directly into the n-th location of the vector (as I would with an array) provides this output (with the same five 1 - 5 inputs):
Your array, unflipped, contains the values:
[0] [5] [5] [5] [5]
No error messages, everything is perfectly legal, I clearly just don't understand how something simple like a vector is implemented here.
I haven't even got to the taxing bit yet - flipping the array! Any advice appreciated.
std::vector<int> user_array (array_size) creates a vector containing array_size zeros. You then use push_back which adds additional elements to the end. You need to create an empty vector using std::vector<int> user_array, and optionally with a capacity of array_size by calling user_array.reserve(array_size). Since your vector starts out empty now, you'll need to change for(auto x : user_array) to a non-range-based loop such as for (int i = 0; i < array_size; i++).
sizeof(user_array) / sizeof(user_array[0]) only works with plain C arrays, not vectors. Use array_size or user_array.size().
In the last range-based for loop, y is the values in the array, not the indices. So print y, not user_array[y].
You seem to be confusing std::vector with C-style arrays.
std::vector<int> user_array (array_size);
initializes user_array with array_size zeroes.
for(auto x : user_array)
{
std::cin >> arr_input;
user_array.push_back(arr_input);
}
As noticed by Alexander Zhang, this piece modifies the vector while iterating over it, which results in Undefined Behaviour. It could result in anything happeining in your program, including infinite loop, crashing completely, supposingly working correct or demons flying out of your nose
index_num = sizeof(user_array) / sizeof(user_array[0]); //or just use array_size-1 instead?
This line makes no sense. You can get the length of vector using its size() method: user_array.size();, but you don't use that variable anyway.
for(auto y : user_array)
{
std::cout << "[" << user_array[y] << "] ";
}
This loop makes no sense either. y is not an index in the vector, it is a value from that vector. If you have a vector {10, 20, 30}, then in first iteration y is equal to 10, in second iteration y is 20 and in third y is 30.
After fixing the errors, your code should look like this:
std::vector<int> user_array ();
std::cout << "Fill your array with integer values. Press 'Enter' after each: " << std::endl;
for(int i = 0; i < array_size; ++i)
{
std::cin >> arr_input;
user_array.push_back(arr_input);
}
std::cout << "Your array, unflipped, contains the values: " << "\n";
for(auto y : user_array)
{
std::cout << "[" << y << "] ";
}
Or for an (invisible) increase in performance, you can reserve the size of the vector before you read it:
std::vector<int> user_array ();
user_array.reserve(array_size);
std::cout << "Fill your array with integer values. Press 'Enter' after each: " << std::endl;
for(int i = 0; i < array_size; ++i)
{
int x;
std::cin >> x;
user_array.push_back(x);
}
This question already has answers here:
Why does my vector print out all zeroes?
(4 answers)
Closed 1 year ago.
I'm trying to show the values of a dynamic array input using vector and a for range loop but when it prints it shows the 0's then the value that was input.
Please don't mind the if statement as I commented it out to use a smaller sample size when testing. But if I enter the size say its 3 then input values such as 1,2,3 the output would be 0 0 0 1 2 3. I'm trying to remove the first three 0's.
int main()
{
std::cout << "How many numerical values do you wish to enter: ";
int values, index, collect;
std::cin >> values;
std::vector<int> numbers(values);
//if(values == 31)
//{
for (index = 0; index < values; index++)
{
std::cout << "Enter value[" << (index + 1) << "]: ";
std::cin >> collect;
numbers.push_back(collect);
}
for (auto &showNumbers : numbers)
{
std::cout << showNumbers << " ";
}
//}
return 0;
}
This line creates a vector of values elements.
std::vector<int> numbers(values);
When you're entering the 3 as values, the vector will hold a three elements with values of 0.
Then you're pushing 3 more elements:
numbers.push_back(collect);
You could either:
replace std::vector<int> numbers(values); with std::vector<int> numbers; (this will create empty vector), or
replace numbers.push_back(collect); with numbers.at(index) = collect; (this will set element value)
Just do numbers[index] = collect; and you are good. You can even try this cin >> numbers[index];
You are using a constructor in
std::vector<int> numbers(values);
In your case:
values = 3
which sets the first 3 contents as zeros. Then using push_back you are adding values further. You must just declare the vector as:
std::vector<int> numbers;
What is the easiest way to read space separated input into an array?
//input:5
1 2 3 4 7
int main() {
int n;
cin>>n;
int array[n];
for (int i =0;i<n;i++){
cin>>array[i];
}
cout<<array;
return 0;
}
I tried the code above but the output is 0x7ffe42b757b0.
The problem lies with your printing. Since array is a pointer, you are only printing an address value.
Instead, do this:
for (int i =0;i<n;i++){
cout<< array[i] << " ";
}
You can do that by passing std::istream_iterator to std::vector constructor:
std::vector<int> v{
std::istream_iterator<int>{std::cin},
std::istream_iterator<int>{}
};
std::vector has a constructor that accepts 2 iterators to the input range.
istream_iterator<int> is an iterator that reads int from a std::istream.
A drawback of this approach is that one cannot set the maximum size of the resulting array. And that it reads the stream till its end.
If you need to read a fixed number of elements, then something like the following would do:
int arr[5]; // Need to read 5 elements.
for(auto& x : arr)
if(!(std::cin >> x))
throw std::runtime_error("failed to parse an int");
array variable always give base address of an array
for (int i =0;i<n;i++){
cout<< array[i] << " ";
cout<<*(array+i)<< " ";
}
Both cout statements will print same only.
in short
array[i] compiler will internally convert into *(array+i) like this only
in the second cout statement from base address of an array it won't add value,since it is an pointer it will add sizeof(int) each time for an increment
I am trying to create an empty vector inside a loop, and want to add an element to the vector each time something is read in to that loop.
#include <iostream>
#include <vector>
using namespace std;
int main()
{
std::vector<float> myVector();
float x;
while(cin >> x)
myVector.insert(x);
return 0;
}
But this is giving me error messages.
You need to use std::vector::push_back() instead:
while(cin >> x)
myVector.push_back(x);
// ^^^^^^^^^
and not std::vector::insert(), which, as you can see in the link, needs an iterator to indicate the position where you want to insert the element.
Also, as what #Joel has commented, you should remove the parentheses in your vector variable's definition.
std::vector<float> myVector;
and not
std::vector<float> myVector();
By doing the latter, you run into C++'s Most Vexing Parse problem.
Use push_back:
while(cin >> x)
myVector.push_back(x);
The insert function takes an iterator as the first argument, indicating the position to insert.
Also, you need to get rid of the parentheses in the declaration of myVector:
std::vector<float> myVector;
If you want to use myVector.insert(),
use it like myVector.insert(myVector.end(), x). This will append x at the end of myVector.
You can insert x in the beginning by myVector.insert(myVector.begin(), x).
Another option is to use std::vector::emplace_back() instead of std::vector::push_back(). The makes some optimizations and doesn't take an argument of type vector::value_type, it takes variadic arguments that are forwarded to the constructor of the appended item, while push_back can make unnecessary copies or movements.
This is demonstrated in the std::vector::emplace_back documentation and here is a related question.
Usage example:
std::vector<int> myVector;
while (cin >> x) {
myVector.emplace_back(x);
}
The code below may answer your question and also brings some other examples regarding how to insert new elements in different position or index.
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int> vector_of_integers{};
vector_of_integers.push_back(1); // O(1)
vector_of_integers.push_back(3); // O(1)
vector_of_integers.push_back(5); // O(1)
vector_of_integers.push_back(7); // O(1)
for (int i = 8; i <= 10; i++)
vector_of_integers.push_back(i);
// Printing out all the elements of vector of integers - Method 1
copy(vector_of_integers.begin(), vector_of_integers.end(), ostream_iterator<int>(cout, " ")); // 1 3 5 7 8 9 10
cout << endl << endl;
// Inserting '2' at index 1
vector<int>::iterator it{ vector_of_integers.begin() };
advance(it, 1);
vector_of_integers.insert(it, 2); // O(N+M) => M is size of elements to be inserted
// Printing out all the elements of vector of integers - Method 2
for (auto const& element : vector_of_integers)
std::cout << element << " "; // 1 2 3 5 7 8 9 10
cout << endl << endl;
// "it" no longer valid, get a new one
it = vector_of_integers.begin();
vector_of_integers.insert(it + 4, 6); // O(N+M) => M is size of elements to be inserted
// Printing out all the elements of vector of integers - Method 3
for (it = vector_of_integers.begin(); it != vector_of_integers.end(); it++)
std::cout << *it << ' '; // 1 2 3 5 6 7 8 9 10
cout << endl << endl;
// insert '4' 7 times at index 3
vector<int> new_vector_to_be_inserted(7, 4);
vector_of_integers.insert(vector_of_integers.begin() + 3, new_vector_to_be_inserted.begin(), new_vector_to_be_inserted.end()); // O(N+M) => M is size of elements to be inserted
// Printing out all the elements of vector of integers - Method 4
for (int i = 0; i < vector_of_integers.size(); i++)
cout << vector_of_integers.at(i) << ' '; // 1 2 3 4 4 4 4 4 4 4 5 6 7 8 9 10
cout << endl << endl;
return 0;
}