Ch 10. 범위, 공간 - 02. 범위

2025. 4. 29. 12:16Programming Language/C++

반응형

범위, 스코프라고 부르는 것은 컴파일 타임에 변수에 접근이 가능한 여부에 대한 것으로 메모리에 할당되고 해제되는것에 대한 영향을 말하는것이 아닌 컴파일타임에 해당 변수에 접근이 가능한지에 대한 내용이다.

우리가 자주 사용하고 자주사용하게될 스코프에 대한 내용을 알아보자.

 

1. 블록 범위(Block Scope)

블록 범위는 {} 중괄호 내부에 선언된 것들을 의미하며 이 중괄호 내부에 선언된 것을은 중괄호 내부에서만 접근이 가능해진다.

그래서 변수의 주소를 확인해보는 코드를 작성해보면 

이렇게 블록 내부에서 접근하는 a의 경우는 블록 외부에서 접근하는 a와는 주소값이 다르고 블록 이전, 이후로도 이 값은 블록 내부 변수의 주소값과는 다르다는것을 볼 수 있다.

 

이건 할당과 해제와는 다르게 스코프에 의해서 블록 내부의 변수에 접근할 수 있느냐는 다르다.

이렇게 블록 내부의 변수에 static을 붙이면 블록이 사라지더라도 해당 변수는 해제 되지 않는데도 불구하고

블록 이후의 a는 블록 내부의 a를 가져서와 사용하지 못한다.

이는 그냥 이렇게 단순하게 블록만을 쓰는것 뿐만 아니라 if문, else문등의 블록 스코프에 해당한다고 본다.

이렇게 선언되어 있는 경우 int i는

이것과 동일하다고 볼 수 있다.

for문 또한 동일하다.

이거는

이것과 동일하다고 볼 수 있기에 블록 스코프로 해당한다고 보면 된다.

 

2. 전역 범위(Global Scope)

전역 범위의 경우는 모든 함수, 모든 블록 바깥에서 선언된 이름(변수, 함수)이 유효한 범위를 말하는 것으로 어디서든 접근이 가능한 범위이다.

 

이렇게 파일 하나에서 선언을 해주고 다른 파일내부에 또 

선언해 준 다음에 빌드해보면

이렇게 여러번 정의된 기호가 있다고 하면서 중복된다고 말한다.

이는 다른 파일에서도 전역 변수는 같은 범위에 존재하기에 동일한 이름으로 변수를 선언하는것이 되기 때문에 발생하는 문제이다.

만약 이렇게 둘 다 선언하려고 한다면 

한쪽에서만 

선언을 해주고 다른쪽에서는 extern이라는 키워드를 사용해서 이 변수는 외부에서 선언되어 있습니다라고 알려줘야만 실행이 가능하다.

그리고 이때는

이렇게 초기화까지 하는 것은 불가능하다 

물론 파일 내부에서 실행되면서 값을 변경하는 것은 가능하다.

extern을 전역적으로 선언하는게 아니라 지역적으로 선언하면 

다른 지역에서는 해당 변수가 존재함을 확인할 수 없게 된다.

 

3. 파일 범위(File Scope)

위에서는 전역변수를 선언하면 어떤 파일에서든 동일한 범위에서 해당 변수를 사용하고 확인할 수 있다고 했는데

여기서 static이라는 키워드를 붙여주면 이제 이 변수는 이 파일에서만 접근이 가능한 변수가 된다.

 

4. 열거형 범위

기본적으로 그냥 사용되는 열거형은 

이렇게 그냥 값 자체를 사용해도 되나 이럴경우에 발생할 수 있는 문제는 

이렇게 같은 값이 다른 enum에 존재할 경우 

이렇게 에러가 발생할 수 있다는 점이다.

그래서 enum class, enum struct를 사용하면

이렇게 특정 enum에 대해서 제한을 두어 같은 명칭이더라도 사용에 문제가 없도록 사용할 수 있다

 

이게 제한된 enum으로써 스코프를 제한을 두는 방법이다.

 

5. namespace 범위

enum의 때와 동일하게 namespace범위라는건 특정 변수, 함수들을 namespace라는 범위로 제한하여 중복되는 명칭으로 혼란을 만들지 않도록 하기 위함이다.

 

예를 들어 내가 A회사와 B회사에서 만든 라이브러리를 구매했다고 해보자.

A는 func라는 함수로 int형 전달인자 두개를 받아 더하는 함수를 만들어 뒀고

B회사도 동일한 함수의 이름으로 int형 전달인자 두개를 받아 곱하는 함수를 만들어 뒀다고 했을때

우리가 func라는 함수를 불렀을때 어떤 함수를 어떻게 가져오고 이 함수들이 전역으로 저장되어 있다면 중복되는 문제가 발생할 것이다.

 

이를 방지하기 위해서 namespace라는 것을 사용한다고 했었는데 이를 각각 사용해서 만들어주면

main함수에서 사용할때 

이렇게 네임스페이스명을 붙여 함수를 어디서 가져온다 제한을 주면 빌드 및 사용할때 문제가 발생하지 않는다.

또한 코드상에서도 이 함수는 어디에서 가져온 함수인지 확실히 구별이 되니 가독성에도 도움을 준다.

반응형