Advice on Sentinel loops C++ - c++

so i get how sentinel loops work, they use the expression at the beginning of the the loop declaration to determine where the loop stops. However i don't understand how to connect variables in the scope of the loop and outside the scope. For example
int i;
int sum = 0;
cout << "Enter a number" << endl;
cin>> i;
while (i > 0)
{
sum = sum + i;
cout << "Enter a number" << endl;
cin>> i;
}
cout << "The sum of the numbers entered is" << endl;
cout << sum;
return 0;
So the sum in the loop is correct since its within scope but the i or number entered to define i out of the scope in the initial i . How do you go about this, can you connect the variables inside and outside the loop? Or can you use uninitialized memory to make a sentinel loop? Do you have to add a separate variable outside the loop and connect the sum of i outside and inside the loop? So just trying to understand how you'd connect the variables inside and outside the scope. If sentinels need to have the variable defined prior to the loop.
Thank you for any light you can shed on this.

Variables are defined in a particular scope and become visible to all scopes within the outer scope unless overwritten (which most programmers tell you is a very, very bad idea). For instance:
#include
using std::cout;
using std::endl;
int main(int, char **) {
int i = 5;
int k = 10;
if (true) {
int j = 15;
int i = 20;
cout << "i inside if: " << i << ". J: " << j << endl;
}
cout << "i outside if: " << i << ". K: " << k << endl;
}
Running it produces:
i inside if: 20. J: 15
i outside if: 5. K: 10
In this case, the scope of method main() contains two variables, i and k. Those variables are also available inside the if-statement. The if also defines two variables, j and i. They are only available inside the if-statement.
The i inside the if-statement hides the larger i (which is dangerous / confusing), but I wanted to demonstrate it. As you can see, i outside the if retains it's original value -- it wasn't modified when we declared the inner copy.
In your code, i and sum are defined outside the if-statement, so they're available inside it, and changes you make to them persist. That is, because you haven't defined new variables, everything just works.

Related

While loop not breaking (I believe)

I don't understand if I have created an infinite loop or it is just taking long.
int wuerfeln_bis_wurfverteilung(Wurfverwaltung ww) { //takes object of class with x number of die rolls
Wurfverwaltung xx(ww.anzahl); //creates object with x (from param.) no. of rolls
cout << xx << endl;
int z=0;
while (!(xx == ww)){ // while the two objects are unequal
Wurfverwaltung xx(ww.anzahl); //keep creating new objects
z++; //and increase z by one
cout <<xx<< " " << z<< " ";
}
return z;
}
//class looks like this
class Wurfverwaltung{
friend int wuerfeln_bis_wurfverteilung(Wurfverwaltung&);
private:
unsigned int anzahl;
Wurf *w; // pointer to an array of objects from a previous class
... bunch of functions
Question: is it always testing for xx from the before the while loop and comparing to ww? or is xx getting updated every loop? the code doesn't seem to break even if I take 2 as the no. of rolls. (answered. Thanks!)
Edit:
The point of the function is to take an object with a random array and recreate an array with the same combination and return the number of attempts it took.
You are shadowing a variable by creating a new variable with the same name in a new scope.
int wuerfeln_bis_wurfverteilung(Wurfverwaltung ww) {
Wurfverwaltung xx(ww.anzahl); // 1
cout << xx << endl;
int z=0;
while (!(xx == ww)){
Wurfverwaltung xx(ww.anzahl); // Creates new variable, doesn't change (1)
z++;
cout <<xx<< " " << z<< " ";
}
return z;
}
If you change it to x = ww.anzahl; you'll be changing the values and maybe exit the loop.
You compiler can help you detect these kind of issues, but you have to activate more flags (-Wshadow in this case on GCC)
The condition of the while loop
while (!(xx == ww)){ // while the two objects are unequal
Wurfverwaltung xx(ww.anzahl); //keep creating new objects
z++; //and increase z by one
cout <<xx<< " " << z<< " ";
}
deals with the variable xx declared before the loop
Wurfverwaltung xx(ww.anzahl);
The variable xx declared within the loop does not influence on the condition of the loop. It just hides the variable declared before the while loop in the compound statement of the while loop. That is the declaration region of the variable declared in the while loop is the compound statement. Outside the compound statement the variable does not exists.
So the initial value of the condition of the while loop
while (!(xx == ww)){
is not being changed and you have an infinite loop.

Subscripted value is not an array, pointer or vector, C++

So, I'm getting the above error (in the title) but for some reason it's only throwing this error on the second loop. Notice the first and second loop I have using the customer variable works absolutely fine, no errors thrown or anything. But on that last loop, the output[customer][charge] array, there is a red line under output[customer] that says "Subscripted value is not an array, pointer or vector". I am using xcode, Mavericks OSX. All of my arrays are defined elsewhere, and have worked perfectly the whole length of the program until now. There are some other operations going on in the program, but they have nothing to do with this loop, so I just posted the code that was giving the error. Again I'll say, the charges[customer][month][charge] loop works fine, but the output[customer][output] is not working.
P.S. You probably will think the logic behind keeping all this data in numerically indexed arrays is dumb, but it is for a school project. So don't lecture me about how this program is logically inconsistent or whatever. Thanks!
string headings[3][7];
string chargeLabels[3] = {"Electricity :","Water: ","Gas: "};
string outputLabels[5] = {"Subtotal: ","Discount: ","Subtotal: ","Tax: ","Total: "};
double charges[3][3][3];
double output[3][5];
for(int customer=0; customer<3; customer++)
{
for(int heading=0; heading<5; heading++)
{
cout << headings[customer][heading];
}
for(int month=0; month<3; month++)
{
cout << chargeLabels[month];
for(int charge=0; charge<3; charge++)
{
cout << charges[customer][month][charge] << ", ";
}
cout << endl;
}
for(int output=0; output<5; output++)
{
cout << outputLabels[output];
//error is below this comment
cout << output[customer][output] << endl;
}
}
Inside the for statement:
for(int output=0; output<5; output++)
{
You declared another variable int output which shadows the double output[3][5] with the same name outside the for statement.
Here's your problem:
double output[3][5];
for(int output=0; output<5; output++)
You're reusing output as a variable name twice.
So when you try to access it here:
cout << output[customer][output] << endl;
You're accessing the local output, which is just an int.

inner loop with same variable name as outer loop

assuming the following simple code:
for(int i=0; i < 1000; i++)
{
cout << "Outer i: " << i << endl;
for(int i=0; i < 12; i++)
{
cout << "Inner i:" << i << endl;
}
}
Works very nice. The same variable name in both loops used and the output is fine.
Do I understand it right that both variables are created on stack, and when the outer loop comes to the new inner loop, a new "namespace" (maybe the wrong name..) is created? But why is it overwritten? If I choose another name for the variable in inner loop I can also access the i from outer loop.
A bit confused I am.
"Namespace" is kinda close.. but it is more about scope. The inner i hides/surpresses the outer i. You could think of another example:
{
int i=0; //outer scope i.
{
int i =0; //this hides the outer scope i.. I can't use outer i here
}
i =1 ; //inner i is out of scope.. outer i is set to 1
}
Your understanding is correct. The code is technically valid. However, this practice has many problems and is therefore a bad idea.
Each for loop has a separate scope associated with it. The variable declared in the inner loop shadows the variable declared in the outer loop. There is no way to access the outer i from the inner loop.

(C++) Specific values in an array

I'm not sure how to title my question, but here goes. I am testing some features, and I have hit a snag.
What I want to know is how can I set up a "for" or "if" statement to only put values in an array that meet a criteria? For example, find every divisor for a number, but only put factors in an array.
Any help would be loved, source code can be provided if needed :). Yes, I am new, so be gentle!
#include <iostream>
using namespace std;
int main(){
int n;
int counter = 1;
cout << "What number would you like to use? ";
cin >> n;
int DiviArray[n];
for (int k=0,j=1;k<n;k++,j++)
{
DiviArray[k] = n-k;
}
int k = 3;
int factn[n];
cout << "Factors of " << n << ": " << endl;
for (int i=0, j=1;i<n;i++,j++)
{
factn[i] = n/DiviArray[i];
if(factn[i]*DiviArray[i]==n)
{
cout << counter << ". " << factn[i] << " x " << DiviArray[i] << endl;
counter++;
}
}
return 0;
}
EDIT: Decided to go with vectors, not sure if I can get it to work, but thanks for the feedback guys :)
Since you don't know in advance how many values will meet the condition, you should use a std::vector.
As a benefit, it keeps track of how many elements you've already added, so push_back will always use the next available index.
This also fixes
cin >> n;
int DiviArray[n];
which isn't legal C++.
If you only want to put the values into the array that match the condition, then you should only put a number into the array when the condition is matched. To do that, the statement that puts a number into the array has to be inside the if-block for the condition. I hope I don't need to explain why :)
This is the only time in your program where you actually do want two indices: one that is incremented every time through the loop (to count how many times to run the process), and one that is incremented only when you put a number in the array (to figure out where the next number goes). Everywhere else, you've created a completely useless j variable (the uselessness should be apparent from the fact that there is no code that actually uses the value, only code to set it).

Does a loop reset every time you go through it?

#include <iostream>
using namespace std;
int main (void) {
cout << " 1\t2\t3\t4\t5\t6\t7\t8\t9" << endl << "" << endl;
for (int c = 1; c < 10; c++) {
cout << c << "| ";
for (int i = 1; i < 10; i++) {
cout << i * c << '\t';
}
cout << endl;
}
return 0;
}
Hey so this code produces a times table...I found it on Google Code's C++ class online...I'm confused about why "i" in the second for loop resets to 1 every time you go through that loop...or is it being declared again in the first parameter?
Thanks in advance!
It "reverts" to 1 because you explicitly set it to 1 as the start condition of the loop...
The "i" name does not exist outside this loop, so each time this loop is run (for each iteration of 'c'), then "i" is a new variable, set to a start of 1.
As TZHX has written. FOR statements usually have three clauses that are in the parantheses (technically they always have three but you don't have to specify them), and a statement that is repeated (often a statement block).
Of those three clauses, the first is an initializer, the second controls the looping, and the third is the increment. So as TZHX says, i is reset to 1 at the beginning due to the initializer clause. This will keep repeating while i<10 (the second clause), and i is incremented by 1 with each iteration (the third clause).