“ for”循环中的“ for”循环可以使用相同的计数器变量名吗?

对于 for循环中的 for循环,我是否可以使用相同的计数器变量?

或者这些变量会相互影响?下面的代码应该为第二个循环使用不同的变量,比如 j,还是 i可以?

for(int i = 0; i < 10; i++)
{
for(int i = 0; i < 10; i++)
{
}
}
26125 次浏览

You may use the same name (identifier). It will be a different object. They will not affect each other. Inside the inner loop, there is no way to refer to the object used in the outer loop (unless you make special provisions for that, as by providing a pointer to it).

This is generally bad style, is prone to confusion, and should be avoided.

The objects are different only if the inner one is defined separately, as with the int i you have shown. If the same name is used without defining a new object, the loops will use the same object and will interfere with each other.

First, this is absolutely legal: the code will compile and run, repeating the body of the nested loop 10×10=100 times. Loop counter i inside the nested loop will hide the counter of the outer loop, so the two counters would be incremented independently of each other.

Since the outer i is hidden, the code inside the nested loop's body would have access only to the value of i of the nested loop, not i from the outer loop. In situations when the nested loop does not need access to the outer i such code could be perfectly justifiable. However, this is likely to create more confusion in its readers, so it's a good idea to avoid writing such code to avoid "maintenance liabilities."

Note: Even though the counter variables of both loops have the same identifier i, they remain two independent variables, i.e. you are not using the same variable in both loops. Using the same variable in both loops is also possible, but the code would be hard to read. Here is an example:

for (int i = 1 ; i < 100 ; i++) {
for ( ; i % 10 != 0 ; i++) {
printf("%02d ", i);
}
printf("%d\n", i);
}

Now both loops use the same variable. However, it takes a while to figure out what this code does without compiling it (demo);

You can. But you should be aware of the scope of the is. if we call the outer i with i_1 and the inner i with i_2, the scope of the is is as follows:

for(int i = 0; i < 10; i++)
{
// i means i_1
for(int i = 0; i < 10; i++)
{
// i means i_2
}
// i means i_1
}

You should notice that they do not affect each other, and just their scope of definition is different.

Yes definitely you can use same name variable.

C programming variables can be declared in three places:
local variables:-Inside a function or a block.
Global variables:-Out of all functions.
Formal parameters:-In the function parameters.

But in your case i scope will have to mind below things

for(int i = 0; i < 10; i++)
{
// i means 1st for loop variable
for(int i = 0; i < 10; i++)
{
// but here i means 2nd for loop  variable
}
//interesting thing here i means 1st for loop variable
}

Note:It would be best practice to use different variables for inner and outer loops

That is completely possible but keep in mind, you wont be able to address the first declared i

for(int i = 0; i < 10; i++)//I MEAN THE ONE HERE
{


for(int i = 0; i < 10; i++)
{


}
}

in the second loop within the second child loop

for(int i = 0; i < 10; i++)
{


for(int i = 0; i < 10; i++)//the new i
{
// i cant see the i thats before this new i here
}
}

if you need to adjust or get the value of the first i, use j in the second loop

for(int i = 0; i < 10; i++)
{


for(int j = 0; j < 10; j++)
{


}
}

and if your creative enough you can do both of them in one loop

for(int i ,j= 0; i < 10; (j>9) ? (i++,j=0) : 0 ,j++)
{
printf("%d %d\n",i,j);
}

Yes you can use the same counter variable name for an inner for loop as for the outer for loop.

From for loop:

for ( init_clause ; cond_expression ; iteration_expression ) loop_statement
The expression statement used as loop_statement establishes its own block scope, distinct from the scope of init_clause.

for (int i = 0; ; ) {
long i = 1;   // valid C, invalid C++
// ...
}

The scope of loop_statement is nested within the scope of init_clause.

From C Standards#6.8.5p5 Iteration statements [emphasis mine]

An iteration statement is a block whose scope is a strict subset of the scope of its enclosing block. The loop body is also a block whose scope is a strict subset of the scope of the iteration statement.

From C Standards#6.2.1p4 Scopes of identifiers [emphasis mine]

....Within the inner scope, the identifier designates the entity declared in the inner scope; the entity declared in the outer scope is hidden (and not visible) within the inner scope.

From a code / compiler perspective this would be a perfectly valid and legal thing to do. The int i declared in the inner for(int i = 0; i < 10; i++) loop is in a new and smaller scope, so that declaration shadows the declaration of int i in the outer loop (or, with other words: In the inner scope all accesses to the variable i go to the int i declared in the inner scope, leaving the int i in the outer scope untouched).

That said, from a code quality perspective this is utterly horrible. It is hard to read, hard to understand and easy to misunderstand. Don't do it.

Yes, you can use it but it's quite confusing. The most important thing is the scope of local variable inside the loop. As far if a variable is declared inside a function, the scope of that variable is that function.

int a = 5;
// scope of a that has value 5
int func(){
int a = 10;
// scope of a that has value 10
}
// scope of a that has value 5

Similarly the case with loops, variable declared inside the inner loop have different scope and variable declared outer loop has different scope.

for(int i = 0; i < 10; i++){
// In first iteration, value of i is 0


for(int i = 1; i < 10; i++){
// In first iteration, value of i is 1
}
// In first iteration, value of i is 0
}

The better approach is to use different variables for inner and outer loops.

for(int i = 0; i < 10; i++){


for(int j = 1; j < 10; j++){


}


}

Yes - and even more interestingly you can reuse a variable name each time you open a set of braces. This is often handy when inserting diagnostic code. Type an open brace '{' followed by declaration and use of variables, then close the brace and the variables go away. This guarantees that you will not interfere with anything in the main body while still retaining the advantage of any variables, classes and methods declared outside the braces.

The important part is that the inner loop parameter contains int i. Because i is redefined this way, the two variables do not affect each other; their scopes are different. Here are two examples to show this:

for(int i = 0; i < 10; i++) // This code will print "Test" 100 times
{
for(int i = 0; i < 10; i++)
{
puts("Test");
}
}

Note that the code above includes int i in the inner loop parameter, and the code below only includes i.

for(int i = 0; i < 10; i++) // This code will print "Test" 10 times
{
for(i = 0; i < 10; i++)
{
puts("Test");
}
}

Scope Rule: A variable declared in a for statement can only be used in that statement and the body of the loop.

If in your code you have defined multiple instances of i in inner loops each instance will occupy its own memory space. So there is nothing to worry about the results anyway it would be the same.

int main(void) {


int i = 2; //defined with file global scope outside of a function and will remain 2
if(1)
{       //new scope, variables created here with same name are different
int i = 5;//will remain == 5
for(int i = 0; i < 10; i++)
{   //new scope for "i"


printf("i value in first loop: %d \n", i); // Will print 0 in first iteration
for(int i = 8; i < 15; i++)
{   //new scope again for "i", variable with same name is not the same
printf("i value in nested loop: %d \n", i); // Will print 8 in first iteration
}
}


}


return 0;
}

But it is not recommended to use the same variable name since it is difficult to understand and it becomes non-maintainable code later.

Well, you can do this without your scripts having a problem, but you should avoid that structure. It usually leads to confusion

Yes you can. But if you want to compare two variables then it will give you a wrong answer because you wont be able to address the first control variable (example here: i).

 for(int i=0; i<queries.size();i++){




for(int i=0; i<strings.size();i++){
        

if(strings[i]==queries[i]){
       

}
}
}

Yes. Here are the relevant quotes from the C11 standard:

If the declarator or type specifier that declares the identifier appears inside a block or within the list of parameter declarations in a function definition, the identifier has block scope, which terminates at the end of the associated block.

If an identifier designates two different entities in the same name space, the scopes might overlap. If so, the scope of one entity (the inner scope) will end strictly before the scope of the other entity (the outer scope). Within the inner scope, the identifier designates the entity declared in the inner scope; the entity declared in the outer scope is hidden (and not visible) within the inner scope.