※ 이전 블로그의 포스트임(2016/11/6)


 

1편에 이어...

 


 

4. 함수 내의 변수 Scope

 교재에서는 기초 단계에서 scope에 대해 다루지 않았고, 나도 특별히 알아 볼 생각은 없었는데, 공부 삼아 코딩을 하다보니, C++ 언어와는 다른 부분이 존재하여 짚고 넘어가려고 한다.

 개발자들 중에 C#을 생애 첫 언어로 삼는 분들은 많지 않을 것이다. 그러므로, 변수 scope 에 대해서 모르는 분들도 별로 없을 것이다. 나 역시 구현 시 몸이 알아서 반응한다.

 너무 익숙하다보니 (경험 상) 당연히 동작해야 할 코드가 빌드 에러를 뱉어 내서 작잖이 당황을 했다.

public static void Main(string[] args)
{
    string text = "Hello";
     
    if( text == "Hello" )
    {
        string text = "World";  // compile error!!!
        Console.WriteLine(text);
    }
}

 

 문제의 코드인데, 7번 줄에서 text 변수가 이미 선언되어 있다더라. 이 상황을 통해 새롭게 알게 된 사실은

 

  C# 에서는 함수 내부의 local scope 개념이 존재하지 않음

 

 즉, 함수 내부에서는 code block을 아무리 열어도 단일 scope로 동작한다는 것이다. C/C++ 숙련자들은 다소 불편할 것 같기는 하지만, 좀 더 합리적인 구현이 가능할 것도 같다.

 

 

5. Reference

 C#에서는 array와 composite type(class..)의 instance가 무조건 heap 영역에 생성 된다. 즉, 함수 내의 해당 변수들은 모두 heap 영역의 특정 위치를 포인팅하는 참조(reference) 변수들이다.

 OOP 언어에 익숙한 개발자라면 이 개념이 익숙하겠지만, C 언어만 사용했던 개발자라면 이 부분을 받아 들이기가 꽤 어렵다. 왜냐하면, C 언어에서는 reference를 위해 '포인터'라는 명시적 표현법을 이용해야 하는데, OOP 언어에서는 일반적으로 묵시적인 표현법을 이용한다. (C++도 참조형이라는 표현이 있지만, 낯섦의 차이는 비교하기 어렵다.)

 C언어에 숙련된 System Programmer(C 언어로 app을 개발하여 돈을 버는 사람은 맹세코 없다.)들이 영역 확장을 시도하다 이 부분에서부터 난관에 부닥치게 되는데, reference 개념에 대한 이해의 문제보다는 바로 표현 방식에서 오는 생소함이 적응을 힘들게 만든다. (포인터를 떡 주무르듯이 다룬 경력이 십수년이라 reference 개념 자체는 오히려 확고한 분들이다.)

 

 여담으로, C++ 에서는 reference를 위해 특별한 notation을 이용하는데, 이를 응용하여 아래와 같은 코딩이 가능하다.

#include <iostream>
 
int main()
{
    int N = 10;
    int& I_am_alias_of_N = N;  // N을 reference
     
    N = 71201;  // N의 값을 바꾸면
     
    std::cout << I_am_alias_of_N << std::endl;  // reference도 바뀜
} 
 
// 출력 결과 : 71201

 

 별명(alias)라고도 부르는 기법인데, 이 게 의외로 도움이 되는 것이 몇 중으로 중첩된 구조체의 필드 값을 사용하고 변경하려고 할 때, 코드가 좀 더 간결해진다. 예를 들어 본다.

#include <iostream>
 
int main()
{
    struct AAAAA
    {
        int n;
    };
     
    struct BBBBB
    {
        AAAAA aaaaa;
    };
     
    struct CCCCC
    {
        BBBBB bbbbb;
    };
     
     
    CCCCC ccccc;   
    int& I_am_alias = ccccc.bbbbb.aaaaa.n;  // ref. 를 이용하여 짧게 만듦
     
    I_am_alias = 981020;  // 접근이 쉬워짐.
         
    std::cout << ccccc.bbbbb.aaaaa.n << std::endl;
}
 
// 출력 결과 : 981020

 

 위와 같이, 길게 늘여 써야 하는 이름을 줄여 쓸 수 있기 때문에 잘만 사용하면 가독성 높은 코드를 만들 수도 있다.

 

 그런데, 

아직 C# 에서는 이런 기능을 발견하지 못했다. 차후에 발견하게 되면 보강할 계획이다.

Posted by JMAN