11장. 포인터 01_ 포인터의 기본 02_ 포인터와 Const
포인터의 개념 포인터 변수는 다른 변수를 가리키는 변수다. 포인터 변수에는 다른 변수의 주소 값을 저장할 수 있다. 예를 들어서 포인터 변수 A가 다른 변수 B의 주소 값을 보관하고 있다면, 포인터 변수 A가 변수 B를 가리키고 있다고 말한다.
변수의 주소 변수의 주소란 변수가 포함하고 있는 제일 첫번째 바이트의 주소를 말한다. 예를 들어서 int 타입의 변수 a가 있다고 하면, 변수 a는 4바이트의 메모리 공간을 소유하게 된다. 메모리의 각 바이트 마다 주소가 있다. 그 중에서 첫번째 바이트의 주소를 변수 a의 주소라고 말한다.
포인터 변수에 변수의 주소를 보관하기 포인터 변수 p가 변수 a를 가리키도록 만드는 예 실행 결과 // 일반적인 변수를 정의한다. int a = 123; // 포인터 변수를 정의한다. int* p; // p가 a를 가리키도록 만든다. p = &a; // 관련 정보를 출력한다. cout << "&a = " << &a << "\n"; cout << "p = " << p << "\n"; cout << "&p = " << &p << "\n";
포인터 변수의 정의 포인터 변수를 정의할 때는 가리키고자 하는 변수의 타입을 지정해 두어야 한다. 다양한 타입의 포인터 변수 char c = 'C'; char* pc = &c; float f = 700.5f; float* pf = &f; bool b = true; bool* pb = &b; short int s = 456; short int* ps = &s;
가리킬 타입을 지정해야 하는 이유 메모리에는 타입에 대한 정보가 보관되지 않는다. 그러므로, 포인터 변수의 타입을 통해서 데이타의 크기나 종류를 알아낸다.
void 포인터 void* 타입의 포인터 변수는 어떤 타입의 변수라도 가리킬 수 있다. void* p;
주소를 사용해서 정보에 접근하기 포인터 변수가 가리키는 변수에 접근하는 예 실행 결과 // p가 a를 가리키도록 만든다. int a = 123; int* p = &a; // p가 가리키는 변수의 값을 얻는다. cout << "*p = " << *p << "\n"; // p가 가리키는 변수의 값을 변경한다. *p = 789; // 관련 정보를 출력한다. cout << "a = " << a << "\n";
포인터 안전하게 사용하기 잘못된 주소를 가진 포인터를 사용하는 것은 매우 위험하기 때문에, 포인터를 사용할 때는 다음의 가이드 라인을 따른다. 포인터 변수는 항상 0 혹은 NULL 값으로 초기화 한다. 포인터 변수를 사용하기 전에는 0 혹은 NULL 값을 가지고 있는지 확인한다. // 포인터 변수를 정의하고 초기화한다. int* p = NULL; // 이 상태에서 포인터를 사용해보자. if (NULL != p) *p = 30; // p가 변수를 가리키게 만들자 int a = 100; p = &a; if (!p)
Const 속성을 가진 변수 변수의 값이 변경되는 것을 막기위해서 Const 속성을 사용해서 변수를 정의할 수 있다. const int a = 123; // a의 값을 바꾸려고 했으므로 컴파일 에러 발생!! a = 456; // 배열의 크기를 const 변수에 보관한다. const unsigned int arraySize = 100; // 배열을 정의한다. char characters[ arraySize ] = {0}; // 배열을 사용한다. for (int i = 0; i < arraySize; ++i) characters[i] = i + 1;
Const 와 포인터 (1) 포인터 변수에 Const 속성을 부여할 때는 다음의 두 변수를 고려할 수 있다. 포인터 변수 자체 포인터 변수가 가리키는 변수
Const 와 포인터 (2) 포인터 변수에 Const 속성을 적용한 3가지 경우를 비교해보자. int i1 = 10; int i2 = 20; const int* p = &i1; p = &i2; // OK *p = 30; // FAIL int i1 = 10; int i2 = 20; int* const p = &i1; p = &i2; // FAIL *p = 30; // OK int i1 = 10; int i2 = 20; const int* const p = &i1; p = &i2; // FAIL *p = 30; // FAIL