What Is the Scope of a 'While' and 'For' Loop

What is the scope of a 'while' and 'for' loop?

In the following examples all the variables are destroyed and recreated for each iteration of the loop except i, which persists between loop iterations and is available to the conditional and final expressions in the for loop. None of the variables are available outside the loops. Destruction of the variables inside the for loop body occurs before i is incremented.

while(int a = foo()) {
int b = a+1;
}

for(int i=0;
i<10; // conditional expression has access to i
++i) // final expression has access to i
{
int j = 2*i;
}

As for why; loops actually take a single statement for their body, it just happens that there's a statement called a compound statement created by curly braces. The scope of variables created in any compound statement is limited to the compound statement itself. So this really isn't a special rule for loops.

Loops and selection statements do have their own rules for the variables created as a part of the loop or selection statement itself. These are just designed according to whatever the designer felt was most useful.

Variable scope in for-loop and while-loop

The $a on line 1 and the $a in the foreach() loop is one and the same object. And after the loop ends, $a has the value 3, which is echoed in the last statement.

According to php.net:

For the most part all PHP variables only have a single scope.

Only in a function does the variable scope is different.

This would produce your desired result '231':

$a = '1';
$c = array('2', '3');
function iterate($temp)
{
foreach($temp as $a)
echo $a ;
}
iterate($c)
echo $a;

Because in the iterate() function, $a is independent of the $a of the calling code.

More info: http://php.net/manual/en/language.variables.scope.php

Scope of declarations in the body of a do-while statement

So currently as a the do while exists the body of the loop is a block:

do 
{ // begin block
int i = get_data();
// whatever you want to do with i;
} //end block
while (i != 0);

so how does a block scope work, from section 3.3.3 Block scope:

A name declared in a block (6.3) is local to that block; it has block scope. Its potential scope begins at its
point of declaration (3.3.2) and ends at the end of its block. A variable declared at block scope is a local
variable.

So clearly the scope of i is the block, so you want a rule that would create some sort of special do while block scope. How would that practically work? It would seem the simplest equivalent would be to hoist the declaration to a newly created outer block:

{
int i = get_data(); // hoist declaration outside
do
{ // begin block
// whatever you want to do with i;
} //end block
while (i != 0);
}

which could possibly work fine if all the declarations where at the start of the body, but what about a scenario like this:

int k = 0 ;
do
{
int i = get_data();
k++ ; // side effect before declaration
int j = k ; // j it set to 1
}
while (i != 0);

after hoisting:

int k = 0 ;
{
int i = get_data();
int j = k ; // j is set to 0
do
{
k++ ;
}
while (i != 0);
}

Another alternative would be to extend the scope from the do while onwards but that would break all sorts of expected behavior. It would break how name hiding works in block scope from section 3.3.10 Name hiding:

A name can be hidden by an explicit declaration of that same name in a nested declarative region or derived
class (10.2).

and example from 3.3.1 shows this:

int j = 24;
int main() {
int i = j, j;
j = 42;
}

the j in main hides the global j but how would work for our special do while scope?:

int j = 24;
do {
int i = j, j;
j = 42;
} while( j != 0 )

Extending the scope of the inner j from the do while forwards would surely break a lot of existing code and looking at the previous example there is no intuitive way to hoist the declaration out.

We could play with this an eventually and find something that works but it seems like a lot of work for very little gain and it is completely unintuitive.

Confuse with variable scope for while and for loop(C programming)

It's very simple:

for(int i = 1 ; ; i++)
{
printf("This is %d\n" , i);
if (i == 10)
break;
}

is equivalent to

{
int i = 1;
while (true)
{
printf("This is %d\n" , i);
if (i == 10)
break;
i++;
}
}

I.e., the int i = 1 part is executed before the first iteration of the for-loop. for introduces an implicit extra scope block holding any variables declared in the X of for (X;Y;Z).

JavaScript: Understanding let scope inside for loop

General Explanation

When you use let in the for loop construct like you show, there is a new variable i created for each invocation of the loop that is scoped just to the block of the loop (not accessible outside the loop).

The first iteration of the loop gets its value from the for loop initializer (i = 1 in your example). The other new i variables that are created each loop iteration get their value from the i for the previous invocation of the loop, not from the i = 1 which is why they aren't all initialized to 1.

So, each time through the loop there is a new variable i that is separate from all the other ones and each new one is initialized with the value of the previous one and then processed by the i++ in the for loop declaration.

For your ES6 code of this:

for(let i = 1; i <= 5; i++) {   setTimeout(function(){       console.log(i);   },100);} 

Scope of a variable ends in a while loop

Just initialize your variable a:

public NewClass() {
int a = 0;
int z = 0;
while (z < 10) {
a = 7;
z++;
}
System.out.println(a);
}

public static void main(String[] args) {
new NewClass();
}

In Java, class and instance variables assume a default value (null, 0, false) if they are not initialized manually.

However, local variables don't have a default value. Unless a local variable has been assigned a value, the compiler will refuse to compile the code that reads it.

Scope of variable inside do-while loop

You can just remove the statement, and add it to the loop condition.

do {
} while (keyboard.nextLine().equalsIgnoreCase("y"));

Variable scope in do while loop

OK so! Thanks to the help of @ibrahimmahrir who put me on the right track, I figured out how to resolve my main issue!

The thing is the fetch() method is asynchronous and I needed to wait (with the await operator) for it to be able to delete the targeted messages.
I also change how I filter the messages to retrieve only the ones I want.

Here is the code :

if (message.channel.id === config.MyChannelID) {
try {
let TargetedMsgsCount // Initializing my variable which I use in my do/while loop
do {
TargetedMsgsCount = 0
await message.channel.messages.fetch({limit:100}).then(messages => {
let Today = new Date()
let TargetDate = new Date(Today.setDate(Today.getDate()-6))
let TargetedMsgs = messages.filter(msg => msg.createdAt < TargetDate)
TargetedMsgs.forEach(TargetedMsg => {
TargetedMsg.delete()
TargetedMsgsCount ++ // So if there is at least one message that match my date condition, there is maybe more
})
})
}
while (
TargetedMsgsCount > 0
)

With that, my loop is now OK!

I have another issue now but that was not my main question and it would be out of topic to ask here so I consider this question closed!

Thanks again to Ibrahim if you read this!

Why is while's condition outside the do while scope

If you'd like to keep value locally scoped for the while loop, you can do this instead:

do
{
Type value(GetCurrentValue());
Process(value);
if (! condition(value) )
break;
} while(true);

This is just personal preference, but I find while loops structured like the following more readable (while instead of do-while):

while(true) {
Type value(GetCurrentValue());
Process(value);
if (! condition(value) ) {
break;
}
}

The scoping rules in C/C++ works as follows: Local variables declared within a brace {...} block is local / visible only to that block. For example:

int a = 1;
int b = 2;
{
int c = 3;
}
std::cout << a;
std::cout << b;
std::cout << c;

will complain about c being undeclared.

As for rationale - it's just a matter of consistency and "that's just how the language is defined"



Related Topics



Leave a reply



Submit