범위

Jaemyeong Lee·2024년 8월 9일
0

FastCampusC++

목록 보기
49/78

C++의 범위(Scope)에 대한 코드 분석

C++에서 변수와 함수의 범위(scope)는 그들이 어디에서 선언되고, 어디에서 접근할 수 있는지를 결정하는 중요한 개념입니다. 이 코드 예제에서는 C++에서 다양한 범위를 활용하는 방법을 보여주며, 각 범위가 어떻게 작동하는지 설명합니다.

1. 전역 변수와 외부 변수의 사용

extern int x;
int y = 10;

int getX()
{
    return x;
}

int getY()
{
    return y;
}
  • extern int x;: x 변수가 다른 파일에서 선언되어 있으며, 이 파일에서 사용할 것임을 알립니다. extern 키워드는 전역 변수를 다른 파일에서 참조할 수 있게 합니다.
  • int y = 10;: y는 정적 전역 변수로 초기화됩니다. 이 변수는 전역 범위에서 접근 가능합니다.
  • getX() 함수: x의 값을 반환하는 함수입니다. x는 외부 파일에서 정의됩니다.
  • getY() 함수: y의 값을 반환하는 함수입니다. 이 파일 내에서 정의된 전역 변수 y를 사용합니다.

2. 전역 변수와 정적 변수의 정의

#include <iostream>
using namespace std;

int x = 10;
int getX();

static int y = 10;
int getY();
  • int x = 10;: 이 파일에서 x 변수가 정의됩니다. 이전에 extern int x;로 선언되었으므로, 다른 파일에서 접근 가능합니다.
  • static int y = 10;: y는 정적 변수로 정의되며, 이 파일 내에서만 접근할 수 있습니다. static 키워드는 변수의 파일 범위(file scope)를 설정하여, 다른 파일에서 접근할 수 없게 합니다.
  • getX()getY() 함수: 앞서 선언된 getX()getY() 함수를 정의하며, 각각 xy 값을 반환합니다.

3. 네임스페이스와 열거형의 사용

enum struct RequestType
{
    Login, Register, Update, Delete
};

namespace CompanyA
{
    int num;
}

namespace CompanyB
{
    int num;
}
  • enum struct RequestType: 이 열거형은 Login, Register, Update, Delete라는 네 가지 상태를 정의합니다. 이 열거형의 이름은 RequestType::Login처럼 RequestType 범위 내에서 사용됩니다.
  • namespace CompanyA, namespace CompanyB: 각각의 네임스페이스 안에 동일한 이름의 변수가 정의되어 있습니다. 네임스페이스는 이름 충돌을 방지하는 역할을 합니다. 예를 들어, CompanyA::numCompanyB::num은 서로 다른 변수를 가리킵니다.

4. main 함수에서의 범위 사용 예제

int main()
{
    {
        // Block scope 
        int a = 0;
        cout << a << endl;
        cout << &a << endl;
        cout << endl;
        {
            static int a = 10; // 블록에 a가 선언되어 상단에서 선언된 a가 가렸음
            cout << a << endl;
            cout << &a << endl;
            cout << endl;
        }

        cout << a << endl;
        cout << &a << endl;  // 최초로 선언 된 a, 블록 내부의 a가 static이기 때문에 해제가 된 것은 아님
        cout << endl;
  • 블록 범위(Block scope): 중괄호 {}로 감싸진 범위 안에서 변수 a가 선언됩니다. 이 a는 블록 내에서만 접근할 수 있습니다.
    • 내부 블록에서 static으로 선언된 a는 외부 블록의 a를 가립니다. 이 static 변수는 프로그램이 종료될 때까지 유지되며, 동일한 블록에 다시 진입해도 이전 값이 유지됩니다.
    • 블록을 벗어난 후에도 외부 블록의 a는 접근 가능하며, static으로 선언된 내부 블록의 a와는 다른 주소를 가집니다.
        if (int num = 1)
        {
            cout << num << endl;
        }

        //num = 1;  접근할 수 없음

        if (int num = 0)
        {
            cout << num << endl;
        }
        else
        {
            cout << num << endl; // else에서는 접근할 수 있음
        }
  • 조건문 내 변수 선언: if 문 내에서 선언된 num 변수는 해당 조건문 블록에서만 유효합니다. else 블록에서도 접근할 수 있지만, if 블록 밖에서는 접근할 수 없습니다. 이는 블록 범위의 또 다른 예입니다.
        for (int i = 0; i < 10; ++i)
        {

        }
        // i = 1; // 접근할 수 없음
  • 반복문 내 변수 선언: for 문 내에서 선언된 i 변수도 해당 반복문 블록 내에서만 유효합니다. 반복문이 끝난 후 i는 범위를 벗어나므로 접근할 수 없습니다.
    {
        // Global scope
        cout << getX() << endl;
        x = 20;
        cout << getX() << endl;
    }
  • 전역 범위(Global scope): x 변수는 전역 범위에서 선언된 변수로, 프로그램의 모든 부분에서 접근 가능합니다. getX() 함수를 통해 x 값을 출력한 후, 값을 변경하여 다시 출력합니다.
    {
        // File scope
        cout << getY() << endl;
        y = 20;
        cout << getY() << endl; // 변하지 않음. 10 출력
    }
  • 파일 범위(File scope): y 변수는 static으로 선언되어 파일 범위를 가집니다. 따라서 y의 값을 변경해도, 이전에 선언된 정적 변수 y는 영향을 받지 않고, 초기값인 10이 유지됩니다.
    {
        // Enumeration scope
        RequestType::Login;
        RequestType::Update;
        RequestType::Register;
        RequestType::Delete;
    }
  • 열거형 범위(Enumeration scope): RequestType 열거형의 멤버는 RequestType::이라는 범위 안에서 사용됩니다. 이는 열거형 멤버 이름이 전역적으로 사용되는 것을 방지합니다.
    {
        // Namespace scope
        // 이름 중복을 피하기 위해 사용.
        // 예를 들어 전역 변수명의 중복을 피할 수 있다
        CompanyA::num;
        CompanyB::num;

        // using namespace 를 사용하여 해당 namespace를 가져올 수 있음
        // using std::cout, cout 만 현재 namespace로 가져옴 
    }
  • 네임스페이스 범위(Namespace scope): CompanyACompanyB라는 서로 다른 네임스페이스에 같은 이름의 num 변수가 정의되어 있습니다. 네임스페이스는 이름 충돌을 방지하고, 코드의 모듈화를 지원합니다.
    • using 키워드를 사용하면 특정 네임스페이스를 현재 범위로 가져올 수 있으며, 이로 인해 코드의 가독성이 향상됩니다. 예를 들어, std::cout 대신 cout을 사용할 수 있습니다.

주요 포인트 정리

  1. 전역 범위(Global scope): 프로그램 전체에서 접근 가능한 변수와 함수가 여기에 포함됩니다. 그러나 전역 변수를 너무 많이 사용하면, 코드의 복잡성과 의존성이 증가할 수 있습니다.

  2. 파일 범위(File scope): static 키워드를 사용하여 선언된 변수나 함수는 해당 파일 내에서만 접근 가능합니다. 이를 통해 다른 파일에서 동일한 이름의 변수가 존재하더라도 충돌을 피할 수 있습니다.

  3. 블록 범위(Block scope): {}로 감싸인 블록 내에서만 유효한 변수들입니다. 이 범위는 프로그램의 흐름을 이해하고, 변수의 수명을 관리하는 데 중요합니다.

  4. 네임스페이스 범위(Namespace scope): 네임스페이스는 이름 충돌을 방지하고 코드의 모듈화를 지원합니다. 이를 통해 코드를 더욱 구조화하고 관리하기 쉽게 만듭니다.

  5. 열거형 범위(Enumeration scope): 열거형 멤버는 열거형 이름으로 구분되는 범위 안에서 사용됩니다. 이를 통해 전역적으로 중복될 수 있는 이름을 방지할 수 있습니다.

profile
李家네_공부방

0개의 댓글