포인터 포인터 포인터
포인터에 대하여서 의문점들이 기억하면 잊고 기억하면 잊고를 반복한다...
확실히 기억에 심어 버리자
포인터는 그냥 얕게 이해하면 쉬운데 깊게 메모리를 파헤치면서 이해하려하면 쉽지는 않다...
그래서 고민하고 실패하고를 반복하면 확실한 정의가 심어질 것으로 생각한다..
시작해봅시다. 포인터 박살내기 프로젝트
1 2 | int a = 10; int *pnData = &a; | cs |
1번행을 해석해보겠습니다.
int a = 10;
int 형식( 4byte 크기만큼을 )스택메모리에 할당하고 a라는 이름으로 그 위치를(주소) 식별하겠다. 그 메모리에는 십진수 10으로 초기화 하겠다.
이것은 기초기 때문에 어렵지 않게 넘어갈 수 있겠죠??
!!참고 '&' 는 단항연산자인 주소연산자입니다. 컴파일타임연산자!(변수의 주소를 넘겨주겠다는 것이죠. )
2번행을 해석해보겠습니다.
int *pnData = &a;
a의 주소를 int에 대한 포인터변수인 pnData의 메모리에 넣겠다는 것입니다.
만약 초기화를 하지 않았을 경우에는? 아래 참고
int *pnData;
pnData는 포인터다. 포인터가 가르키는 값을 int로 지정하고 해석하겠다.
가르키는 대상을 int형 변수로 해석하겠다는 뜻입니다.
실질적으로 메모리를 보게 되면 pnData의 메모리에는 a의 주소가 들어있습니다.
그렇다면 화면에 출력할때는 어떻게 해야할 것인가??
참조할코드
1 2 | printf("%d\n", pnData); printf("%d\n", *pnData); | cs |
1. printf("%d",pnData);
이런 방식으로 호출을 한다면... 결과 값은 pnData에 들어있는 a의 주소가 "10진수 형태로 변경되서" 출력됩니다
2. printf("%d",*pnData);
이런 방식을 사용하면 a의 값이 잘 나타날 것입니다. 10이 나옵니다!
무슨 문제 때문에 결과 값이 이렇게 나오는 것일까....??
참고로 '*'은 간접지정연산자 입니다. 지정이라는 말은 메모리의 길이와 해석방법을 뜻합니다.
가르키는 대상의 자료형을 지정한다는 뜻이죠
위의 그림과 같이 가르키고 있는 대상의 메모리를 자료형에맞게 지정하겠다는 뜻이죠.
1번 출력문을 해석해보겠습니다.
printf("%d",pnData);
이 문단에서 pnData == (int*)pnData 같은 의미가 됩니다.
즉, pnData의 자료형은 무엇인가요?? (int*) 형태지요? 그리고 pnData는 a의 주소를 가지고있지요?
그러므로 pnData 자체는 a의 메모리를 가지고 있기 때문에, a의 메모리 주소가 출력되는 것입니다.
==================================================================================
그렇다면!!
==================================================================================
2번 출력문을 해석해보겠습니다.
printf("%d",*pnData);
pnData는 int에 대한 포인트변수라고 했고 a의 주소를 담고있다고 했습니다.
여기에 '*' 간접지정 을 하게 되면 담고있는 주소에 대한 지정을 하게 되는 것입니다.
즉 pnData가 담고있는 주소를(가지고있는 값) '*' 간접지정하여 int에 대한 변수로 보겠다는 것입니다.
- *(int*) -> int
- 지정된 것을 한번 간접 지정하면 변수가 나온다는 것 기억합니다.
함수로 응용해서 포인터 뿌쎠버리기!!##!#!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | #include<stdio.h> void Myfunc(int *pnData_a, int *pnData_b){ printf("%d\n",*pnData_a); printf("%d\n",*pnData_b); } int main(void) { int nData = 10; // int로 지정된 변수 nData선언하고 10으로 정의한다. int *pszData = &nData; // nData의 주소를 포인터함수에 넣는다. Myfunc(&nData, pszData); return 0; } |
11번 행에서 nData 선언및 정의를 하였습니다.
12번 행에서 int에 대한 포인트함수 pszData를 선언하며 초기화를 &nData 주소로 하였습니다.
14번 행을 보기전에 Myfunc()함수 먼저 보겠습니다.
Myfunc(int *pnData_a, int *pnData_b) 매개변수로 포인터변수 "pnData_a, pnData_b" 를 선언하였습니다.
이 말은 주소를 받아야한다는 것이겠죠?? ( 주소를 받지 않아도 값을 받을 수 있습니다. 이말은 조금 뒤에 설명할겠습니다.)
■ 주소를 받아야하니 13번 행에서 주소를 넘겨줍니다. (&nData, pszDtat)
- &nData는 "&" 주소연산자로 인해서 주소로 넘겨주는 것이기에 주소가 넘어가는 것이 맞구요.
- pszData를 넘겨주었는데, 왜 &pszData로 넘겨 주지 않았냐고 하실 수 있습니다. &로 넘겨주면 pszData의 주소가 넘어갑니다....
우리가 원하는 값은 pszData안에있는 주소입니다!! 만약 &pszData이렇게 넘겨 주소를 받게된다면, 간접지정연산자 '*' 한개로는 원하는 값을 얻을 수 없습니다.
결론은 pszData를 넘겨줌으로써 pszData안의 값이(혹은 주소) 넘어가게 된다는 것이죠.
이렇게 매개변수를 주소값으로 넘겨주면 Myfunc함수에서는 간접지정하여 출력만 해주면 마무리게 됩니다.
계속해서 궁금한 것은 채워 나가겠습니다.
주소를 받지 않아도 값을 받을 수 있다는 것도 조만간 올리겠습니다.
'훈, IT 공부 > C,C++,MFC' 카테고리의 다른 글
[C/C++] C++에서의 클래스와(Class) C언어 에서의 구조체 비교해보자 (0) | 2018.01.31 |
---|---|
[프로그램]복권(로또)게임 #랜덤으로 뽑기(자동) (0) | 2018.01.30 |
[프로그램]숫자 야구 게임 (3) | 2018.01.24 |
[독하게C]함수에 대한 기본이론과 사용 주의점!! (feat.전역변수) (0) | 2018.01.18 |
헝가리안 표기법이란 (0) | 2018.01.04 |
댓글