CPP_어소_25_정적변수 외부변수

CJB_ny·2022년 5월 24일
0

CPP_AROTHO

목록 보기
23/83
post-thumbnail

접근 제한도 "기능"이다.

extern -> 알려주기만 한다.

변수 물어보면 지역, 전역, 정적, 외부 인지 분류


여기 int g_i = 0;

전역변수 만들고

func.cpp에 int g_i = 0; 라는 전역변수 만들었을 경우

했을 경우 컴파일 단계는 그냥 넘어간다.

컴파일은 각자 파일 단위로 해서 "목적 파일"인 obj 파일이 나온다.
각 파일 단위로

그래서 각각 파일 단위로봤을 때는 문제가 없다.

그런데 프로그램을 만드는 "빌드"라는 과정에서 파일들을 합치는 과정에서

링킹이라는 과정이 있다.

이 과정에서

전역변수가 같은 이름으로 두가지가되어 문제 발생.

정적변수

Data 영역 쓴다고 했던거 알제?? (ㅇㅇ 안다)

그런데 g_i 나 g_iStatic이란 변수 둘다 main함수 내에서

사용이 가능한데 뭔 차이인가?

(솔직히 나도 방금 생각한게 뭔차인지 싶다...)

그런데

빌드 할 경우

이상태와

이상태에서 빌드 할 경우

문제가 없다..!!

정적 변수는 선언되는 위치에 따라서 동작이 조금씩 차이가 있다.

하지만 정적변수의 "static" 키워드가 의미하는 공통적인 의미 == 뜻 자체는 변하지 않는다.

static == 정적이다.

뜻 자체를 기억!

static은 이렇게 선언된 곳에만 있는 것이다.

밖에서는 저 안의 static i가 있는줄 모른다 => 콕 박혀있으니까

저 static i 가 있는 필드 내에서는 i가 있는 줄 안다.

그래서 애내들은 main.cpp, func.cpp라는 곳에 콕 박혀서 선언된 애들이라

즉, 해당 파일에서만 존재 하는 애들이라.

전역변수에서 발생했던 문제가 애내들 한테는 발생하지 않는다.

main.cpp, func.cpp에서 호출한 g_iStatic이 구별이 된다.

출신지가 달라서 같은 이름이더라도 구별이 가능하다.

함수안에 static

Test함수내에 선언된 경우

Test함수에 고정이 되어서 안 움직인다.

그 이미지를 떠올려라

그럼 함수안에 static은 Stack? Data?
Data영역에 사용된다.
static은 데이터 영역에 사용된다 했으니까

(그런데 함수를 호출하면 그것은 Stack에 쌓임)

Test함수 호출

이렇게 호출을 하면

main위에 Test가 사용할 만큼 호출 스택이 메모리에 할당된다.

그런데 static int i = 0;
은 여기 호출 스택에 포함이 안되어 있다.

static int i는 프로그램이 시작하고 끝날때까지 존재하는 Data영역에 이렇게 존재를 한다.

그런데 선언된 위치가 Test함수 내라 Test함수 내에서만 동작을 한다.

i는 Test함수 지역 출신이라 Data영역에 있더라도 선언위치가 달라 main함수에서 호출 할 수 없다.

정리

Test함수안의 static int i = 0; 는 (정적변수를 특정함수 안에 선언 할 경우)

static이라 데이터 영역에 있다.

  • 데이터 영역은 프로그램 실행과 동시에 생성이 되어 프로그램이 종료될 때까지 존재하는 메모리 영역이다.

정적변수를 특정함수 안에 선언 할 경우 해당 함수 안에서만 사용할 수 있으면서

그 특정 함수가 호출되가나 종료되거나 할 때에

Stack메모리를 사용하지 않기 때문에

해당 함수의 호출과 종료에 따라서 해제 되거나 종료되지 않고

유지되는 메모리 이다.

그런데 사용하는 것은 그 특정 함수(선언된 함수) 내에서만 사용이 가능하다.


그러면 시발 이게 필요한가?

전역변수는 상시 유지 시키고 싶을 때 선언하면됨 -> 데이터 영역

이럴경우 이게 맞나?

누가 실수나 일부로 수정해버리면??

그런 문제.

Test 호출2

이렇게 되면 Test호출 될 때마다 0을 집어 넣고 있지 않네??

이런경우는 문법적 특징인데

함수가 호출 될 때마다 해당 값(0)을 집어 넣겠다는게 아니라

그 함수에서만 접근 가능한 데이터 영역의 정적 변수의 초기값을 0을 주겠다. 라는 뜻이고, 그다음부터는 초기화 구문이 계속 실행하지 않고 건너 뛰게 된다.

C++ 문법 기준 정적 변수 static 초기화 구문은 최초의 한번만 실행되고 건너 뛰게 된다.

모든 파일에서 인식할 수 있는 전역변수 extern

우리가 그래서 common.h 에 static int _common이라는 거 만들어놓고

main.cpp, func.cpp에서 include하게 되면

우리가 원했던 상황인 모든 파일에서 같은 변수를 인식하나?

NO -> include는 복붙만 하는 것이다.

이런 상황일 경우

그러면 main, func의 각각의 g_istatic이 같은 녀석인가??

노노 그냥 각자 파일마다 정적 변수 하나씩 있는 거다.

문제

이렇게 선언하고 main.cpp, func.cpp 에서 include로

i의 값을 수정 하거나 출력을 하게되면

이런 링킹 단계의 에러가 발생 컴파일 단계에서는 발생 안함.

extern이라는 문법을 몰라서 그렇데

CPP에서 extern은 이렇게 절대 초기화를 하면 안된다.

여기서는 extern int g_iExtern이라는 변수를 "선언"한게 아니라

그냥 알려주기만 하는 것이다.

그냥 있을 꺼다~ 하고 알려주는 거임.

정리

extern int i;라는 i가 있다고만 common.h에 알려주는 역할만 해주고

main.cpp, func.cpp에서는 i로 이것저것 작업을 한다.

진짜 "실체"는

test.cpp 라는 파일을 만들어서 안에

int i = 10;

이런식으로 초기화를 해주면된다.

내가 정리

extern 있다고 알려주면

어드 파일에서든지 상관없이 전역변수 선언 해주듯이

이렇게 초기화를 한번 해주면된다.

profile
https://cjbworld.tistory.com/ <- 이사중

0개의 댓글