기존에 C++ primer 관련해서 변수 관련해서는 따로 정리하지 않겠다고 이야기 했지만,
결국에는 정리하게 되었다.
꽤나 나 자신이 모르거나 헷갈려하던 내용이 많던 이유가 그 중 하나이다.
1. extern 변수
- extern 변수는 기본적으로 선언만 하고 초기값을 넣지 않은 변수이다.
extern double j; //j를 선언하지만 초기화를 하지 않음.
int i = 10; //i를 선언하고서 상수(숫자)로 초기화.
때문에 이는 .cpp파일이 아닌, .hpp파일에서 사용하면
더 유용하게 사용이 가능하다.
참고로 extern으로 정의한 변수에 초기값을 지정할 수 있다.
extern double pi = 3.1416 //pi를 선언하면서 정의.
이렇게 할 경우엔 extern를 컴파일러가 무시한다.
(결국에 위쪽의 int형 i처럼 일반적인 변수와 같아진다는 소리이다.)
2. 복합타입자 선언 이해하기.
- 기본적인 내용이지만, 변수 선언 후 즉시 초기값을 설정할 때
정의문 하나에서 타입이 다른 변수를 정의할 수 있다.
//int에서 i는 int, p는 int에 대한 포인터, r은 int 에 대한 참조자이다.
int i = 1024, *p = &i, &r = i;
//int에서 p1은 int에 대한 포인터, p2는 int이다.
int *p1, p2; //즉, p1만 포인터 이다.
3. 포인터에 대한 포인터
- 포인터는 메모리에 있는 객체이므로, 다른 객체처럼 주소가 있다.
즉, 포인터의 주소를 다른 포인터에도 저장 할 수 있다.
int ival = 1024;
int *pi = &ival; //pi는 int ival를 가리킨다.
int **ppi = π //ppi는 ival의 주소를 가리키는 포인터 pi를 가리킨다.
이에 대해서 조금더 풀어서 다시 설명하자면,
이렇게 볼 수 있겠다.
* <---일반적인 포인터
** <--포인터에 대한 포인터
*** <-포인터에 대한 포인터의 포인터
4. 포인터에 대한 참조자
- 참조자는 객체가 아니다. 즉, 별칭(별명)이라고 이해하면 쉽다.
때문에 참조자에 대한 포인터는 없다.
but, 포인터는 객체이므로 포인터에 대한 참조자는 정의가 가능하다.
int i = 42; //객체(int)
int *p; //p는 int i에 대한 포인터.
int &r = p; //r은 포인터 p에 대한 참조자.
r = i; //r은 포인터를 참조하니, &i를 r에 대입하면 p는 i를 가리킴.
*r = 0; //r를 역참조시 p로 가리키는 객체 i를 반환한다.
즉, i를 0으로 변경가능.
5. const 한정자(상수)
- 주로 어떤 변수나 함수의 값이 변경되지 않기를 바랄때 많이 쓰는 키워드.
사용법은 아래와 같다.
만약 아래 bufsize의 값을 변경하려고 할 시에는 컴파일러 에러가 난다.
const int bufsize = 512;
추가로 const를 사용할 수 있거나 사용하지 못하는 경우를 설명하자면, 아래와 같다.
cosnt int i = get_size(); //성공 : 사이즈 함수 값을 넣음.
const int j = 42; //성공 : 상수(숫자)로 변수를 초기화.
const int k; //Error : 초기화를 하지 않음.
즉, cosnt를 변수에 사용할 시에는 무조건 선언과 동시에 초기값을 지정해 줘야 한다.
(그렇지 못하면 에러.)
또 하나의 사용예시를 들어보자면,
int i = 42;
const int ci = i; //i값을 ci로 복사.
int j = ci; //ci값을 j로 복사.
ci를 복사해서 j에 초기화 할 때 j가 const인지는 중요하지 않다.
왜냐하면 기본적으로 const 객체는 지역(local)적으로 반응하기 때문이다.
즉, 여러파일에서 같은 이름으로 const변수를 정의하면 별개의 변수 선언이다.
때문에 사용시 헤더(*.hpp)파일 하나에 const변수를 선언하고 그 객체를 사용하는 다른 파일에서는 정의를 하는 게 좋을 것이다.
아래에 예시를 들어보자면..
//cpplearning.hpp 헤더파일
extern const int i;
이렇게 사용할 시 cpp파일에만 사용을 하는게 아닌,
여러 cpp파일에서도 해당 헤더파일을 사용하고선 확장하여 사용이 가능하다.
6. 포인터와 const
- 참조자(&)와 달리 포인터(*)는 객체이므로 포인터도 const일 수 있다.
참고로 참조자도, 포인터도 접근자체는 가능하지만,
const 객체로 설정된 변수의 내부 값(데이터)를 변경하는 것은 불가능하다.
참고로 const 포인터 객체는 자신이 가리키는 변수 값이 const인지는 알 수 없다.
int errNumb = 0;
int *const curErr = &errNumb; //curErr는 항상 errNumb을 가리킴.
const double pi = 3.14159;
const double *const pip = &pi //pip는 const객체에 대한 포인터이다.
이외에도 const와 포인터, 그리고 참조자에 대한 자세한 내용들은
이후 포스트에서 다시 공부하며 기록해보겠다.
이번 포스트는 여기까지!
'Game DevTip > C++' 카테고리의 다른 글
6. C++ string 타입에 대해서 (0) | 2024.12.05 |
---|---|
5. C++ auto & decltype에 대해서. (0) | 2024.12.05 |
4. C++ Typedef(타입 별칭)에 대해서 (0) | 2024.12.05 |
3. C++ constexpr에 대해서 (1) | 2024.12.05 |
2. C++ const에 대하여 (0) | 2024.12.05 |
댓글