3. http://blog.naver.com/ruvendix
간접 참조 연산자
변수의 주소를 알아내려면 주소 연산자 &을 사용하면 됨!
그런데… 거꾸로 메모리 공간의 주소에서 값을 알아내려면 어떻게 해야 하지…?
어떻게 하긴! 주소 연산자처럼 새로운 연산자를 하나 더 만들자!
그리고 그 연산자의 이름을 간접 참조 연산자(역참조 연산자)라 하자!
&iNum이 메모리 공간의 주소를 의미한다면…
*(&iNum) 이렇게 다시 iNum을 참조하자!
4. http://blog.naver.com/ruvendix
포인터의 모습
포인터는 반드시 선언할 때 *을 식별자 앞에 붙여야 함!
그래야 컴파일러가 포인터로 인식할 수 있음!
당연한 얘기지만 포인터도 변수임!
포인터는 32비트 시스템인 경우 4바이트,
64비트 시스템인 경우 8바이트의 크기를 가짐
포인터는 주소의 증감 연산이 가능함!
단! 포인터끼리는 뺄셈만 가능!
6. http://blog.naver.com/ruvendix
const 예약어(상수로 만든다)
포인터가 원본의 값을 변경할 수 있기 때문에…
보안을 강화해야 한다!
const int *pNum = &Num;
이러면 pNum은 Num의 값을 변경할 수 없음!
하지만 다른 주소를 가리킬 수는 있음!
int * const pNum = &Num;
이러면 pNum은 다른 주소를 가리킬 수 있음!
하지만 Num의 값을 변경할 수는 있음!
const int * const pNum = &Num;
이러면 완벽한 보안!
다른 주소를 가리킬 수도 없고 값을 변경할 수도 없음!
7. http://blog.naver.com/ruvendix
void 포인터
모든 자료형을 가리킬 수 있는 만능 포인터도 있을까?
있다! void 포인터가 그런 존재!
void *Perfect;
char cNum;
Perfect = &cNum;
*(char *)Perfect;
int iNum;
Perfect = &iNum;
*(int *)Perfect;
double dNum;
Perfect = &dNum;
*(double *)Perfect;
void 포인터를 사용할 때는 형변환 필수!
8. http://blog.naver.com/ruvendix
더블 포인터
함수를 호출할 때 인자를 넘기면 매개변수는 그 인자를 복사받는다
그러면… 포인터가 가리키는 주소를 함수에서 변경할 수 있을까…?
더블 포인터를 사용하면 가능하다!
int *pNum1 = &iNum1;
int *pNum2 = &iNum2;
void Swap(int **pp1, int **pp2)
{
int *pTemp = *pp1;
*pp1 = *pp2;
*pp2 = pTemp;
}
10. http://blog.naver.com/ruvendix
포인터 배열과 배열 포인터
포인터는 배열로도 만들 수 있다!
포인터 배열을 가리키려면 더블 포인터가 있어야 함!
char StringArray[7][10];
char (*pStringArray)[10] = StringArray;
배열 포인터와 비슷하지만 처리 순서가 다름!
배열 포인터는 배열의 길이를 가리키는 포인터!
(단! 2차원 배열 이상부터 가능!)
11. http://blog.naver.com/ruvendix
함수 포인터
같은 형식이면서 의미가 비슷한 함수가 여러 개 있을 때
그 함수들을 관리할 수 있는 포인터를 사용하고 싶다!
그렇다면 함수 포인터가 딱임!
반환 형식이 void이고 매개변수가 void인 함수가 있다고 하자!
ShowCircle(), ShowRectan
gle(), ShowEllipse(), ShowSquare()
void (*pShowFigure[4])(void) =
{ShowCircle, ShowRectangle, ShowEllipse, ShowSquare};
pShowFigure[0](); // ShowCircle() 호출
pShowFigure[1](); // ShowRectangle() 호출
pShowFigure[2](); // ShowEllipse() 호출
pShowFigure[3](); // ShowSquare() 호출
(함수 포인터 배열은 이렇게 만들어야 함!)