The scope of a local variable is the whole of the block in which it is declared, including the part of the block before it.
So in your first example, the variable declared on the last line is in scope even though it can't be used (because you can't use a variable before its declaration).
You can't declare a local variable when another local variable with the same name is in scope, which is why the first snippet fails.
The second snippet fails because the scope of the variable declared in the for loop is only the for loop itself.
It might make more sense to remove loops from the picture entirely, and just use blocks. Your first example is similar to this:
// Outer block
{
// Inner block
{
// Error due to the i variable declared in the outer block
int i = 0;
}
// Scope of this variable is the whole of the outer block
int i = 0;
}
Your second example is similar to this:
// Outer block
{
// Inner block
{
// This declaration is fine, and the scope is the inner block
int i = 0;
}
// This is invalid, because there's no variable called "i" in scope
i = 0;
}