Indexing issue with a for loop - c++

I have a for loop where I'm using the slide operator as I'm working with unsigned types. Essentially it boils down to
for (std::size_t i = 6; i --> 0;){
cout << i;
}
But it outputs the numbers from 5 to 0 inclusive and omits 6. Why?
Thank you very much for looking at this. I'm quite stuck.

This is a touchstone for
The fact that this so-called "operator" should be used with caution, if at all.
Changing the state of variables within the conditional check of a for loop ought to be done with extreme caution, if at all.
The largest output is 5 simply because i is decremented as a result of the conditional test which also decrements i. The conditional check is ran before program control enters the for loop body.
You really ought to rewrite the loop. Don't set the initial value of i to 7 as that's a dirty hack. Although --> is often used with while (and to emphasise, it's unlikely to win you many friends in your programming review), I've never seen it used with a for loop before.

--> is not a slide operator.
It is understood by the compiler as two different operators -- and >.
So your code look like this to the compiler:
for (std::size_t i = 6; (i--) > 0;){
cout << i;
}
Since the loop condition is checked before entering the loop's body i is decreased before the first execution of the loop's body, hence the produced sequence of numbers is 5 4 3 2 1 0.
For more details see this Stack Overflow question: What is the "-->" operator in C++?

After evaluating this condition in the for statement
i --> 0
i will be equal to 5. So the first iteration of the loop outputs
5
To achieve the effect you want rewrite the loop the following way
#include <iostream>
int main()
{
size_t i = 6;
do
{
std::cout << i;
} while ( i-- > 0 );
return 0;
}
The program output is
6543210
Another way is the following
#include <iostream>
int main()
{
for ( size_t i = 6; std::cout << i && i != 0; i-- )
{
//
}
return 0;
}
Of course you could write the loop like this
const size_t N = 6;
for ( size_t i = N + 1; i-- > 0; )
// ^^^^^^^
{
std::cout << i;
}
However in general this approach does not work when the initial value of i is equal to std::numeric_limits<size_t>::max() Because if to add 1 to this value you will get 0.
A general approach using a for loop can look the following way
#include <iostream>
int main()
{
const size_t N = 6;
for ( size_t i = N, j = N; j != 0; j = i-- )
{
std::cout << i;
}
return 0;
}
Its output is
6543210

Related

What can I use to stop a loop instead of 'return 0'?

so I made a simple loop that finds out if an array has the elements with the values of 0 and 1.
if the loop indeed finds 0 or 1 inside of the array, it will say "YES", otherwise "NO".
yes, the program works just fine, but at the end of the program it prints out "YES" or "NO" as many times as i put cin>>dim to.
for example if dim which means (dimension[of the array]) is 5 it's going to print either "YESYESYESYESYES" or "NONONONONO"
I have to use return 0 in order to make it print it out like once, but I feel like this is not the right way to do it. Please help me with this. thanks!
#include <bits/stdc++.h>
using namespace std;
int main()
{
int i, dim, v[100];
cin>>dim;
for(i=0;i<dim;i++)
cin>>v[i];
for(i=0;i<dim;i++)
if(v[i]==0 || v[i]==1){
cout<<"YES"; return 0;}
else{
cout<<"NO"; return 0;}
return 0;
}
The break statement can be used to break out of loops. The example from cppreference:
for (int j = 0; j < 2; j++) {
for (int k = 0; k < 5; k++) { //only this loop is affected by break
if (k == 2) break;
std::cout << j << k << " ";
}
}
As the comment suggests, break only breaks the innermost loop.
In your code you always exit from the loop on the very first iteration, hence you do not need the loop in the first place. This will have the same output as your code:
int main() {
int i, dim, v[100];
cin >> dim;
for(i=0; i < dim; i++)
cin >> v[i];
if(v[0] == 0 || v[0] == 1) {
cout << "YES";
} else {
cout << "NO";
}
}
After reading the question again...
I made a simple loop that finds out if an array has the elements with the values of 0 and 1
If you exit the loop after checking the first element then you only check the first element. If you want to see if an array contains only 1 or 0 or it contains at least one element which is 0 or 1 (not 100% clear which one you want), then you rather need this:
bool only_zero_or_one = true;
bool one_zero_or_one = false;
for (int i = 0; i < dim; ++i) {
zero_or_one = ( v[i] == 0 | v[i] == 1);
only_zero_or_one = zero_or_one && only_zero_or_one;
one_zero_or_one = zero_or_one || one_zero_or_one;
}
Only for one_zero_or_one you can break the loop once zero_or_one == true.
Moreover, you should rather use a std::vector. In your code, if the user enters a dim which is greater than 100 you write beyond the bounds of v. This can be avoided easily:
size_t dim;
std::cin >> dim;
// construct vector with dim elements
std::vector v(dim);
// read elements
for (size_t i=0; i < v.size(); ++i) std::cin >> v[i];
// .. or use range based for loop
for (auto& e : v) std::cin >> e;
but I feel like this is not the right way to do it
Returning is an entirely right way to break out from a loop.
Another right way is the break statement, which jumps to after the loop.
Even better, you can actually check if v[i]==0 or 1 inside the input for loop immediately after taking input and set a flag to true. Depending on requirement, you can either break or wait until the entire input is read and then come out and check for flag==true and then print "YES" and print "NO" if flag==false.
This will save you running the loop again to check for 0 or 1.

How do I add the elements of this vector together?

The purpose of my code is to add the elements of a vector together into one integer. This is for Problem #1 on Project Euler:
https://projecteuler.net/problem=1
Here is my code:
int main()
{
int max_count = 1000; //The upper bound
//Loop for filling vector
for (int i = 1; i <= max_count; ++i){
int counter[max_count];
if (counter[i] % 3 == 0|| counter[i] % 5 == 0){
vector <int> start_point = {};
start_point.push_back (counter[i]);
for (auto& n : start_point){
int sum_of_elems = 0;
sum_of_elems += n;
cout << sum_of_elems;
}
}
}
return 0;
}
Currently, my code is outputting the following and I cannot figure out why.
32766143547943202305202750000-4646761603276630-76434810000-76434582500-464677056327662448-4646770403276632766-46467703232766327666032766230586999-970904238-95777621723084852023084852032766-970904244-46467688032766230624075-970911300230826120-1916976912327663276623063434032766230634681-957776214230826120140084992032766-970911280327660003276603276630-4646761603276623058081332766-464676440327663276632766230831712230745153065793306031200003276623074515300-191647711200023084852023074515365793360036000002308224802307451533657937207200-46467616032766000023083171232766230595552230831712032766327660-46467619232766230577342230822480230829920000-46467616032766230822480230829960-46467264032766230540223001920409600-46467247232766327661920409600-46467220832766000000000011072962560230556921230818160-4646738403276619204096000000230510592-1572142422000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001920169263100000170147416279176918919693827240000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
You're reinitializing your sum variable on each loop, so you end up just printing the individual values. You're also mixing looping and summing, which is complicating your code; either skip the vector entirely (just have a summing loop), or fill it completely, then sum it.
I can't give much more useful advice because you've got a lot of associated problems here. You declare counter without initializing it, then read from uninitialized memory to populate start_point.
Point is, most of your variables need to be declared outside the loops (so they're not repeatedly reinitialized from scratch on each loop), your output should be after the loops, and counter needs real data so you're not invoking undefined behavior.
Removing vectors and other unnecessary variables, the code can be simplified to:
#include <iostream>
int main()
{
int max_count = 1000; //The upper bound
int sumOfMultiples = 0;
for (int i = 1; i < max_count; ++i)
if (i % 3 == 0 || i % 5 == 0)
sumOfMultiples = sumOfMultiples + i;
std::cout << "Sum of Multiples of 3 and 5 below 1000 is: " << sumOfMultiples << "\n";
return 0;
}
Output is:
Sum of Multiples of 3 and 5 below 1000 is: 233168

While loop task in c++

I am a beginner in c++ and I am having problems with making this code work the way I want it to. The task is to write a program that multiplies all the natural numbers up to the loaded number n.
To make it print the correct result, I divided x by n (see code below). How can I make it print x and not have to divide it by n to get the correct answer?
#include<iostream>
using namespace std;
int main(){
int n,x=1;
int i=0;
cout<<"Enter a number bigger than 0:"<<endl;
cin>>n;
while(i<n){
i++;
x=i*x;
};
cout<<"The result is: "<<x/n<<endl;
return 0;
}
At very first a principle you best get used to as quickly as possible: Always check user input for correctness!
cin >> n;
if(cin && n > 0)
{
// valid
}
else
{
// appropriate error handling
}
Not sure, why do you need a while loop? A for loop sure is nicer in this case:
int x = 1;
for(int i = 2; i < n; ++i)
x *= i;
If you still want the while loop: Start with i == 2 (1 is neutral anyway) and increment afterwards:
i = 2;
while(i < n)
{
x *= i;
++i;
}
In case of n == 1, the loop (either variant) simply won't be entered and you are fine...
You already have two very good options, but here is an other one you might want to take a look at when you are at ease enough in programming :
unsigned factorial(unsigned value)
{
if (value <= 1)
{
return 1;
}
else
{
return value * factorial(value - 1);
}
}
It's a recursive function, which is kind of neat when used in proper moments (which could not be the case here unfortunately because the execution stack might get so big you fill your memory before you're done. But you can check it out to learn more about recursive functions)
When your memory is full, you then crash your app with what is called actually a stack overflow.
How can I make it so that in the last cout I can only put x and not have to divide x by n to get the correct answer?
It will be better to use a for loop.
// This stops when i reaches n.
// That means, n is not multiplied to the result when the loop breaks.
for (int i = 1; i < n; ++i )
{
x *= i;
}
cout << "The result is: " << x <<endl;

Increment ++i, i++ and i+=1

I am beginner in C++. What I understand is that:-
i++ is executing first, then increment, ++i is increment first, then execute,i+=1 is increment by 1,then execute. But in the FOR loop:
for (i=0;i<10;i++)
for (i=0;i<10;++i)
There is really no difference in these two loops above.
Here is another one to calculate the sum of all integers from 1 to 100:
int i=1, sum=0;
while (i<=100)
{
sum+=i;
i++; //i+=1; ++i;
}
cout<<sum<<" "<<i<<endl;
return 0;
But if I replace i++ with i+=1 or ++i, they all return a sum of 5050 and i of 101. So I really don't see any difference in them.
So could anyone explain this to me? Which one of those is used most in programming? Thank you!!
You are correct. In your examples there is no difference.
But here there is:
int i = 0;
cout << i++ << endl; //prints 0
cout << i << endl; //prints 1
vs
int i = 0;
cout << ++i << endl; //prints 1
cout << i << endl; //prints 1
Which one of those is used most in programming?
Most of the time, ++ is the only operation in the statement (FYI, a for loop has three statements).
If it isn't, then it might matter, and you'll use whichever one gives you the correct behavior.
FYI
Some developers have the opinion that if pre and postfix operators should always be used alone (not part of a large statement). They can lead to confusing code, or even undefined behavior.
For example,
int i = 0;
cout << i++ + i++ << endl;
has undefined behavior.
So could anyone explain this to me?
What i++ does is return the current value of i and then increment it by one, and ++i first increment i by 1 and then returns the value of i.
Take a look at this, for example:
i = 5;
j = 5;
res = i++; //res = 5, but i=6
res = ++j; //res = 6 and j=6
Which one of those is used most in programming?
Both are used depending on what you want or may be how you want.
One more thing to note:
++i is an l-value, but i++ is not. For details see here
Your analysis is correct. i++ will return the value of i, then increment, whereas ++i will increment the value of i, then return the new value. i += 1 will do the same as ++i. The difference in where they will be used in actual code is primarily situational; there's no specific answer as to where each of them are most often used or helpful. It all depends on what you want to do.
Here's a contrived example of one time it might be useful to use post-increment (i++ form):
// Return the length of a string, including the null byte
int stringLength(char str[])
{
int length = 0;
while (str[length++] != 0);
return length;
}
If you wanted to return the length without the null byte, you could modify the above example slightly, using the ++i form:
// Return the length of a string, without the null byte
int stringLength(char str[])
{
int length = -1;
while (str[++length] != 0);
return length;
}
As for i += 1, I don't think I've ever done quite that, since you can use pre- or post-increment instead. I've generally only used the compound assignment operators for values other than 1.
I think if you imagine how the for loop works you can understand the problem at hand.
for loop
initialization --> i = 0
<check condition> --> i<10? ------->--------------------
| | |
^ |yes(i.e condition not met) |no(i.e condition met)
| V V
| --------------
| |body of loop|
| --------------
| |
| V
-------<------------increment i (**) exit for loop
** increment i means i++ or ++i
i++ can be replaced by this :
int temp = i;
i = i + 1;
temp will be useless here so the compiler will optimize it to just inc i instruction. even if it doesn't do that temp is just a waste of space that's all.
++i can be replaced by
i = i + 1;
int temp = i;
again temp is not required so the compiler will just replace it with inc i instruction.
if you see both the instruction are the same because they are not being assigned to anything. only i is being affected by the increment. so both are essentially the same. this is true if i is a built-in type .
you see that the increment instruction is placed after the body of the loop? can you now see that this is almost similar to the while loop that you showed?
it is always nice to think of loops in this way.

Loop not giving expected answer - unsure about exit/return/break

I am testing a simple piece of code in order to learn about using queues (as well as practizing vectors).
I have written this piece of code:
#include "stdafx.h"
#include <iostream>
#include <queue>
struct msgInfo //contains the attributes as gleaned from the original (IP) message
{
int age;
std::string name;
};
using namespace std;
int main ()
{
vector<vector<queue<msgInfo>>> nodeInc; //container for messages
int qosLevels = 7; //priority levels
int nodes = 5; //number of nodes
vector<queue<msgInfo>> queuesOfNodes(qosLevels);
int i;
for (i=0; i<nodes; i++)
{
nodeInc.push_back(queuesOfNodes);
}
msgInfo potato, tomato, domato, bomato;
potato.age = 2;
potato.name = "dud";
tomato.age = 3;
tomato.name = "bud";
domato.age = 4;
domato.name = "mud";
bomato.age = 5;
bomato.name = "pud";
nodeInc[2][2].push(potato);
nodeInc[2][2].push(tomato);
nodeInc[2][3].push(domato);
nodeInc[2][3].push(bomato);
for (int j = 0; j < 2; j++) //simple loop for testing: for each round, output the age of only one 'msgInfo'
{
cout << j << endl;
for (int k = (qosLevels-1); k >= 0; k--)
{
if (!nodeInc[2][k].empty())
{
cout << nodeInc[2][k].front().age << endl;
nodeInc[2][k].pop();
return 0;
}
else
break;
}
}
}
The output I get is
0
1
but what I am trying to get is
0
4
1
5
What am I doing wrong here? I can't figure out where my logic is wrong - it seems to me that here it should output the first two elements belonging to the highest filled priority level. I think it has to do with how I am exiting the loop - essentially I want each round of the for loop to only output the age of one msgInfo before 'pop'-ing it - but I have tried exit/return/break and it hasn't worked.
edit
I am receiving messages from nodes. These messages need to be put into a queue according to their attributes: node and priority level. I have decided to use a vector<vector<queue<msgInfo>>> to do this -> essentially node < priority level < queue for messages > >. When accessing this container, I need it to output the age of one msgInfo at a time - the msgInfo will be the front of the queue of the highest priority level. Not all priority levels will be filled, so it needs to iterate from highest priority level to lowest in order to find the relevant element.
I need to design a loop that will output these one at a time (because other processing needs to be done between each round of the loop).
The closest I can get to is this:
for (int j = 0; j < 2; j++) //simple loop for testing: for each round, output the age of only one 'msgInfo'
{
cout << j << endl;
for (i = (qosLevels-1); i >= 0; i--)
{
if (!nodeInc[2][i].empty())
{
cout << nodeInc[2][i].front().age << endl;
nodeInc[2][i].pop();
//return 0; <--------DON'T return. this terminates the program
break;
}
//else
// break;
}
}
That returns:
0
4
1
5
As is stated in the comment, invoking return 0; returns from main() and therefore terminates the program ( actually kind of a peaceful exit ).
What do you expect return 0 and break to do?
return 0 exits the entire main function, so your program would end once it encounters a non-empty queue.
break terminates the innermost enclosing loop (which is for (i ...)). In other words, your current logic is:
For each j of 0, 1 do:
If nodeInc[2][qosLevels - 1] is not empty, print its front and exit program; otherwise try no more is and do next j.
I don't know what the intended behaviour is, but based on the "expected output" you gave, you should replace return 0 with break, and omit the else clause entirely.