728x90
728x90
SMALL
정적변수 static
void doSomething()
{
static int a = 1;
++a;
cout << a << endl;
}
int main()
{
doSomething(); // 2 출력,첫 호출! 이 때 a의 초기화가 1로 처음이자 마지막으로 이루어진다.
doSomething(); // 3 출력
doSomething(); // 4 출력
doSomething(); // 5 출력
}
정적 변수 static 변수의 특징
- 초기화는 처음 호출될 때 딱 한번 만 한다.
ο 초기화를 반드시 해주어야한다.
■ static int a; ← 에러
ο 처음 호출되는 doSomething) 에서 a 가 처음이나 마지막으로 딱 한번 초기화 된다.
■ static int a = 1; - But static 변수의 데이터 값은 메모리에 유지된다. 값이 유지됨.
ο 떄문에 OS로부터 받은 메모리가 정적 이라는 뜻
ο a 가 static 변수가 아니였다면 doSomething 호출시마다 새롭게 1로 초기화되 매번 1 출력했을 것.
ο a 값이 유지 되기 떄문에 doSomething 호출시마다 2, 3, 4, 5, . . . 가 출력되는 것이다. - 해당 블록 안에서만 사용이 가능하다. 지역변수
ο static 변수인 a 는 doSomething) 호출시에만 사용된다.
■ doSomething 블록내에 있으니까 !
ο 이것이 전역변수 와의 차이점 !
■ 전역 변수 는 코드 내의 모든곳, 심지어 다른 파일에서도 사용될 수 있다.
■ static 변수 는 메모리 값이 유지된다는 면에서 전역 변수와 비슷하지만 지역변수로서 해당 블록에서만 사용이 가능하다.
■ cf) 다른파일과의 linking 단계에서 지역변수를 고려할 필요 X
■ 해당 파일 내의 블록 내에서만 쓰이니까.
전역 변수
- main 함수 밖에서 선언된,
- 어떤 { } 중괄호 안에서도 귀속되있지 않는 변수
- 지속 기간이 없다. 프로그램 종료 때 사라짐.
- 웬만해서 최소한으로 쓰는 것을 추천한다.
전역 변수의 종류
- static 붙은 전역변수 → 이 cpp 파일 내에서만 사용 가능
- extern 붙은 전역변수 → 다른 파일에서도 사용이 가능함과 동시에 메모리 공유된다.
ο extern 생략 가능하다. 전역변수는 디폴트로 extern.
■ 디폴트로 전역변수, 전역함수는 다른 파일에서도 사용 가능
linking 링킹
- include 한 다른 코드 파일과 연결하는 작업
- 컴파일러가 링킹 시 include 한 다른 코드 파일 전체를 복사해오는 식으로 작업함
extern
- 초기화 꼭 해주기
ο extern int a;
■ 이렇게 선언만 해놓으면 쓰레기값만 들어가 있는거니까 다른 파일에서 사용하려고 할때 이상한 값 나올 수도.
■ 여기선 선언만 하더라도 다른 파일에서라도 꼭 초기화 해주어야함!
■ 초기화는 꼭 주인 파일에서 해야한다는 법은 없고 한군데서만 꼭 하면 됨. - extern 으로 선언된 변수와 함수
ο 이미 메모리에 할당되어있는 초기화가 되있는 다른 파일의 전역 변수와 메모리를 공유하겠다고 선언할 때는 키워드 생략 할 수 없다.
aaa.h
int a = 123;
- extern 키워드 생략이 가능
- 그냥 다른 파일에서 복사해서 쓰셔도 되요~ 라는 의미의 전역변수에는 extern 생략 가능
ο 내 파일에서만 사용 가능하다는 의미일땐 static 붙여야 하고
main.cpp
#include "aaa.h"
using namespace std;
extern int a;
int main()
{
cout << a << endl; // 123 출력
}
- aaa.h 의 전역변수 a 와 메모리 공유를 할것이기 때문에 extern 으로 선언 !
ο 이때의 a 는 aaa.h의 a를 뜻한다 !
ο aaa.h 의 a 와 메모리를 공유할 것이라고 선언하는 것 !
■ 이런 의도일땐 extern 생략 불가
■ extern 안붙이고 그냥 int a 하면 이건 aaa.h의 a와의 메모리 공유가 아닌 그냥 main.cpp에서의 새로운 int a 를 선언하는 것.
MyConstants . h
namespace Constants
{
const double pi(3.141592);
const double gravity(9,8);
}
main . cpp
#include "MyConstants.h"
int main()
{
cout << Constants::pi << endl;
}
- #include “MyConstants.h”
ο extern이 붙지 않은 상태
■ 따라서 main.cpp 에서의 Constants::pi 와 MyConstants.h 에서의 pi 는 별개의 pi다.
■ 메모리 공유 X
■ 즉, 이름만 같지 서로 다른 변수라는거다.
■ MyConstants.h 에서 복사해온 것 뿐. - 이런 경우, Myconstants.h 가 다른 곳에서 1000번 include 된다면 pi 변수의 사본만 1000개 생기는거니 매우 메모리 낭비.
- 값이 바뀔 위험이 없는 const 전역 변수들 은 extern을 붙여서 계속 복사되서 메모리 늘릴 필요 없이 메모리를 공유해서 쓰일 수 있도록 하는 것이 좋다. ⭐⭐
아래와 같이 MyConstants.h 에 extern 을 붙여준다면
namespace Constants
{
extern const double pi(3.141592);
extern const double gravity(9,8);
}
- linking 시에 컴파일러가 내부적으로
ο main.cpp 에서 include 한 Myconstants.h 코드들을 복사사해온다.
ο 눈엔 안보이지만 아래와 같이 되는 것
#include "MyConstants.h"
namespace Constants
{
extern const double pi(3.141592);
extern const double gravity(9,8);
}
int main()
{
cout << Constants::pi << endl;
}
ο 이제 MyConstants.h 의 pi의 사본을 쓰는것이 아닌
ο MyConstants.h 의 pi자체 메모리를 공유하게 된다.
MyConstants . h
namespace Constants
{
extern const double pi;
extern const double gravity;
}
MyConstants . cpp
#include "MyConstants.h"
Constants::pi = 3.141592;
Constants::gravity = 9.8;
- 보통 이렇게 헤더파일에선 extern 변수를 선언만 하고
- 초기화는 헤더 파일과 같은 이름의 cpp에서 해주는 것이 일반적.
ο MyConstants.cpp 에서 내부적으로 MyCOnstants.h 에서의 pi 와 공유하는 것을 뜻하는 extern const double pi; 가 복사되어 옴 - MyConstants . cpp 에서 선언한게 아니고 대입하여 초기화 해준것임.
정리
- extern이 생략된 extern 전역변수
ο 다른 파일에서 사본으로 씀. 별개의 메모리. - extern이 붙어있는 extern 전역변수
ο 다른 파일에서도 이와 한 메모리를 공유. 동일한 메모리.
/* 초기화 X */
int g_x; // external. 다른 파일에서 사본으로 쓰인다.
static int g_x; // internal. 다른 파일에서 쓰일 수 없다. 이 코드 내에서만 쓰일 수 있음
const int g_x; // external. 에러! const는 꼭 초기화를 해주어야함
extern int g_z; // 이 파일을 include 하는 다른 파일에서 이 변수와 메모리를 공유하게 될 것.
extern const int g_z; // 에러 아님! 이 변수와 메모리를 공유하는 다른 파일에서 초기화 꼭 해주면 됨.
/* 초기화 O */
int g_y(1); // external.
static int g_y(1); // internal.
const int g_y(1); // external.
extern int g_w(1); // 이제 다른 파일에서 정의가 불가능하다.
extern const int g_w(1);



728x90
300x250
LIST
'C │ C++ │ C# > C++' 카테고리의 다른 글
C++ Chapter 4.4 : auto와 자료형 추론, 형변환 | 2023.08.19 |
---|---|
C++ Chapter 4.3 : using문과 모호성 | 2023.08.19 |
C++ Chapter 4.1 : 지역 변수, 범위, 지속 기간 | 2023.08.18 |
C++ Chapter 3.3 : 비트끼리의 연산, 비트 플래그, 비트 마스크 | 2023.08.17 |
C++ Chapter 3.2 : 이진수 | 2023.08.17 |