IT

for-loop에 선언 된 변수는 지역 변수입니까?

lottoking 2020. 6. 27. 10:38
반응형

for-loop에 선언 된 변수는 지역 변수입니까?


C #을 오랫동안 사용해 왔지만 다음을 깨달은 적이 없습니다.

 public static void Main()
 {
     for (int i = 0; i < 5; i++)
     {

     }

     int i = 4;  //cannot declare as 'i' is declared in child scope                
     int A = i;  //cannot assign as 'i' does not exist in this context
 }

그렇다면이 이름으로 변수를 선언 할 수 없다면 for 블록 외부에서 'i'값을 사용할 수없는 이유는 무엇입니까?

for-loop가 사용하는 반복자 변수는 해당 범위에서만 유효하다고 생각했습니다.


for-loop 외부와 for-loop 외부에서 동일한 이름의 변수를 정의 할 수없는 이유는 외부 범위의 변수가 내부 범위에서 유효하기 때문입니다. 이것이 허용된다면 for-loop 내에 두 개의 'i'변수가 있음을 의미합니다.

참조 : MSDN 범위

구체적으로 특별히:

local-variable-declaration (8.5.1 절)에 선언 된 지역 변수의 범위는 선언이 발생하는 블록입니다.

for 문의 초기화에 대해 선언 된 지역 변수의 범위 (섹션 8.8.3)는 초기화 장치, 조건, for-iterator 및 for 문의 포함 명령문입니다.

또한 지역 변수 선언 (C # 사양의 섹션 8.5.1)

구체적으로 특별히:

local-variable-declaration에 선언 된 로컬 변수의 범위는 선언이 발생하는 블록입니다. 로컬 변수의 로컬 변수 선언 앞에있는 텍스트 위치에서 로컬 변수를 참조하면 오류가 발생합니다. 지역 변수의 범위 내에서 같은 이름으로 다른 지역 변수 나 상수를 선언하는 것은 컴파일 타임 오류입니다.

(Emphasis mine.)

이는 ifor 루프 내부 의 범위가 for 루프 임을 의미합니다 . ifor-loop 외부의 범위 는 전체 주요 방법 for-loop입니다. 의미 i는 위와 같이 유효하지 않은 루프 내부에 두 번 발생 한다는 의미 입니다.

허용되지 않는 이유 루프 내에서만 사용할 수 int A = i;있기 때문 int i입니다 for. 따라서 더 이상 for루프 외부에서 액세스 할 수 없습니다 .

보시다시피이 두 가지 문제는 범위를 벗어난 결과입니다. 첫 번째 문제 ( int i = 4;)는 루프 범위 i에서 두 개의 변수를 생성합니다 for. 반면 int A = i;범위를 벗어난 변수에 액세스 할 수 있습니다.

대신 할 수있는 i것은 전체 메소드에 범위가 지정되어 선언 하고 메소드와 for 루프 범위 모두에서 사용하는 것입니다. 이렇게하면 규칙을 어 기지 않아도됩니다.

public static void Main()
{
    int i;

    for (i = 0; i < 5; i++)
    {

    }

    // 'i' is only declared in the method scope now, 
    // no longer in the child scope -> valid.
    i = 4;

    // 'i' is declared in the method's scope -> valid. 
    int A = i;
}

편집 :

물론 C # 컴파일러는이 코드가 상당히 유효하게 컴파일되도록 변경 될 수 있습니다. 결국 이것은 유효합니다 :

for (int i = 0; i < 5; i++)
{
    Console.WriteLine(i);
}

for (int i = 5; i > 0; i--)
{
    Console.WriteLine(i);
}

그러나 코드 가독성 및 유지 관리가 다음과 같은 코드를 작성할 수 있다면 실제로 도움이 될 것입니다.

public static void Main()
{
    int i = 4;

    for (int i = 0; i < 5; i++)
    {
        Console.WriteLine(i);
    }

    for (int i = 5; i > 0; i--)
    {
        Console.WriteLine(i);
    }

    Console.WriteLine(i);
}

여기서 실수의 가능성에 대해 생각해보십시오. 마지막으로 i0이나 4를 인쇄합니까? 이제 이것은 매우 작은 예입니다. 추적하기 쉽고 추적하기 쉽지만 외부 i이름을 다른 이름으로 선언 한 것보다 유지 관리가 쉽고 읽기 쉽습니다 .

NB :

Please note, C#'s scoping rules differ from C++'s scoping rules. In C++ variables are only in scope from where they are declared until the end of the block. Which would make your code a valid construct in C++.


J.Kommer's answer is correct: briefly, it is illegal for a local variable to be declared in a local variable declaration space that overlaps another local variable declaration space that has a local of the same name.

There is an additional rule of C# that is violated here as well. The additional rule is that it is illegal for a simple name to be used to refer to two different entities inside two different overlapping local variable declaration spaces. So not only is your example illegal, this is illegal too:

class C
{
    int x;
    void M()
    {
        int y = x;
        if(whatever)
        {
            int x = 123;

Because now the simple name "x" has been used inside the local variable declaration space of "y" to mean two different things -- "this.x" and the local "x".

See http://blogs.msdn.com/b/ericlippert/archive/tags/simple+names/ for more analysis of these issues.


There is a way of declaring and using i inside the method after the loop:

static void Main()
{
    for (int i = 0; i < 5; i++)
    {

    }

    {
        int i = 4;
        int A = i;
    }
}

You can do this in Java (it might originate from C I'm not sure). It is of course a bit messy for the sake of a variable name.


If you'd declared i before your for loop, do you think it should still be valid to declare it inside the loop?

No, because then the scope of the two would overlap.

As for not being able to do int A=i;, well that's simply because i only exists in the for loop, like it should do.


In addition to J.Kommer's answer (+1 btw). There's this in the standard for NET scope:

block If you declare a variable within a block construct such as an If statement, that variable's scope is only until the end of the block. The lifetime is until the procedure ends.

Procedure If you declare a variable within a procedure, but outside of any If statement, the scope is until the End Sub or End Function. The lifetime of the variable is until the procedures ends.

Thus the int i decalared within the for loop header will be in scope only during the for loop block, BUT it's lifetime lasts until the Main() code completes.


The easiest way to think about this is to move the outer declaration of I to above the loop. It should become obvious then.

It's the same scope either way, therefore can't be done.


Also C#'s rules are many time not necessary in terms of programing strictly, but are there to keep your code clean and readable.

for example, they could have made it so that if you define it after the loop then it is ok, however it someone who reads your code and missed the definition line may think it has to do with the loop's variable.


Kommer's answer is technically correct. Let me paraphrase it with a vivid blind-screen metaphor.

There is a one way blind screen between the for-block and the enclosing outer block such that the code from within the for-block can see the outer code but the code in the outer block cannot see the code inside.

Since the outer code cannot see inside , it cannot use anything declared inside. But since the code in the for-block can see both inside and outside , a variable declared at both places cannot be used unambiguously by name.

So either you don't see it , or you C# !


Look at it in the same way as if you could declare an int in a using block:

using (int i = 0) {
  // i is in scope here
}
// here, i is out of scope

However, since int does not implement IDisposable, this can not be done. It may help someone visualize how an int variable is placed in a private scope, though.

Another way would be to say,

if (true) {
  int i = 0;
  // i is in scope here
}
// here, i is out of scope

Hope this helps to visualize what is going on.

I really like this feature, as declaring the int from inside the for loop keeps the code nice and tight.

참고URL : https://stackoverflow.com/questions/7992332/variable-declared-in-for-loop-is-local-variable

반응형