inner loop with same variable name as outer loop - c++

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.

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.

Advice on Sentinel loops 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.

How to solve undeclared variable in the case below

I am a beginner at c++ and I want to ask about this specific error. I don't know why it always appears that I didn't declare the variable wherein in fact, I did (see my code below).
You initiated the decoder array in both cases in an if statement. So the compiler does not know it outside of the if. Write the variable before your first if-else statement and than change it, if needed, within the if statement.
The problem is in the array declaration, it is declared inside of a scope:
#include <iostream>
using namespace std;
int main()
{
int a = 2; // local variable
if (true)
{
int a = 4; // local if statement variable
cout << a << endl; // here the output will be 4
}
cout << a << endl; // here the output will be 2, also here 'a' from the if statement, does not longer exist, when the if statement is ended all the variables declared inside will be deleted
return 0;
}
You can also create your own scope with out 'if' statement:
int a = 2; // local variable
{
int a = 4; // local scope statement variable
cout << a << endl; // here the output will be 4
}
cout << a << endl; // here the output will be 2, also 'a' from the previous scope does not exist
Here is a useful link to learn about local variables and scope.
Your particular problem is that your variable decoder is local to the block scope (you declared it within a if statement), and you try to use it outside that scope. However, once exited the scope, all variables local to that scope are destroyed.
if (number = 987)
{
int decoder[3] = {0, 1, 2};
} // and here decoder is destroyed
You could declare decoder outside the block and define it inside the block:
int decoder[3];
if (number = 987)
{
// populate decoder
}
// decoder still exists

Symbol table using vectors

I've been racking my brain trying to figure out the logic with implementing my symbol table & now I'm waving the white flag and asking for some help. I'm creating a symbol table using vectors but I'm having trouble putting the symbol table entry (a string for now, a struct later) in the right scope. My code has an int scopenum that increments every time a block is opened { and decrements every time a block is closed }. However this line causes a problem:
{ a { b } { q } } because it puts q in scope 2 when it should be in scope 3. My code pushes a new row onto the vector but it doesn't use it in the insert. How can I modify my code to correctly account for opening & closing scopes?
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
int stacknum=-1;
vector< vector<string> > v;
void display(){
for(int i=0; i<v.size(); i++){
cout << "Scope " << i+1 << ": " << endl;
for(int j=0; j<v[i].size(); j++)
cout << v[i][j] << endl;
cout << endl;
}
}
void insert(string s){
v[stacknum].push_back(s);
}
int main(){
string data;
ifstream file;
file.open("input");
if(!file.is_open()) {
cout << "Input file not found";
return 1; }
while(file >> data){
if(data=="{"){
stacknum++;
vector<string> row;
v.push_back(row);
continue;
}
if(data=="}"){
stacknum--;
continue;
}
insert(data);
}
file.close();
display();
return 0;
}
You can't track the current scope with just a index; you need a stack. Alternatively (and probably more usefully) you need to record the parent scope for each scope, which you can do with a second vector or by including an extra data member in the scope object.
In either case, when you enter a new scope, you create a new scope object (a vector of symbols, with associated parent scope index) at the end of the vector of scope objects, and make that object's index the "current scope index". When you leave a scope, the current scope index is set to the current scope's parent.
The parent pointers are useful when you are searching for a symbol; you need to search all of the parents of the current scope until you find the symbol.
Depending on the scoping rules you are trying to model, that might not be adequate. It doesn't accurately model C's scoping rules, for example, because in C, the scope of a declared variable starts at the declaration, not at the beginning of the enclosing block. However it may be good enough for building an AST, as long as you do all symbol lookups in order as you parse the input left to right.

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).