|
http://www.hackerschool.org/HS_Boards/zboard.php?AllArticle=true&no=1741 [복사]
출저= 때릴꺼야
원본= http://blog.naver.com/ani4ever/120026820947
*----------------------------------------------------------------------------------------------------------*
이 카테고리는 그동안 배웠던것이라던가 공부하면서 알게된 내용들을 중심으로 혹여 참고가 될 수 있을까 싶은 내용들을
모아둔 곳입니다. 따라서 이 글들을 대상이 되는 분들은.. 프로그래밍을 갓 시작했거나 개념이 마구마구 흔들리시는 분들
정도가 되겠습니다. 그러니 너무 욕하지는 말아주세요 =_=;;;
혹시 제가 잘못 알고 있는 부분들이라던가 궁금한 것이 있으면 쪽지 남겨주시거나 리플을 달아주시면 감사하겠습니다.
*----------------------------------------------------------------------------------------------------------*
포인터의 사용 부분은 나중에 설명하기로 하고 우선 왜 포인터가 다양한 형을 갖는지 살펴보도록 하겠습니다.(이걸 알면 다차원 포인터니 뭐니 하는 고급 사용 부분은 이해가 좀 더 쉬워집니다)
포인터는 앞에서 '주소를 저장하는 int형 크기의 변수'라고 이해했습니다.
즉, [char*]가 됐건 [double*]가 됐건 심지어 [class*]가 됐건 모두 int크기(4Byte)를 갖는 정수형 변수에 불과합니다. 어차피 정수형 주소를 저장할거라면 차라리 pointer라는 별도의 포인터형을 만들어서 사용하면 헷갈리지도 않고 편할텐데 왜 구지 char*니 double*이니 일일이 만들어 사용을 하는걸까요?
앞서 사용했던 메모리 블럭 그림을 다시 가져와서 보도록 하죠..
(□ 한칸은 1Byte, 초기화되지 않은 상태로 무슨 값이 들어가 있는지는 알수 없음)
0 1 2 3 4 5 6 7 8 9 a b c d e f 0 1 2 3 4 5 6 7 8 9 a b c d e f
0x0- □□□□ □□□□ □□□□ □□□□ □□□□ □□□□ □□□□ □□□□
0x2- □□□□ □□□□ □□□□ □□□□ □□□□ □□□□ □□□□ □□□□
0x4- □□□□ □□□□ □□□□ □□□□ □□□□ □□□□ □□□□ □□□□
0x6- □□□□ □□□□ □□□□ □□□□ □□□□ □□□□ □□□□ □□□□
여기에 int형 변수 2개와 char형 변수 3개, double형 변수 2개를 선언했다고 생각해보죠.
그럼 아래와 같이 변수 블럭이 세팅 될것 입니다.
int iNum1, iNum2;
char cChar1, cChar2, cChar3;
double dNum1, dNum2;
0 1 2 3 4 5 6 7 8 9 a b c d e f 0 1 2 3 4 5 6 7 8 9 a b c d e f
0x0- □□□□ □□□□ □□□□ □□□□ □□□□ □□□□ □□□□ □□□□
0x2- □□□□ □□□□ □□□□ □□□□ □□□□ □□□□ □□□□ □□□□
0x4- □□□□ □□□□ □□□□ □□□□ □□□□ □□□□ □□□□ □□□□
0x6- □□□□ □□□□ □□□□ □□□□ □□□□ □□□□ □□□□ □□□□
여기에 각 변수를 위한 포인터 변수를 하나씩 선언을 해서 사용한다고 했을때
pointer p1 = &iNum1;
pointer p2 = &cChar1;
pointer p3 = &pdNum1;
(pointer는 [포인터 데이터 타입]이라고 가정하고)
이라고 하면 p1은 0x00을, p2는 0x08, p3는 0x0c 라는 값을 각각 갖게 됩니다.
자.. 이제 이 값을 참조해 봅시다.
*p1은 메모리의 어디서부터 어디까지를 참조해야 될까요? p1이라는 변수명만으로 p1이 참조하는 메모리의 데이터 타입을 알 수 있을까요? p2는? p3는?
만약 pointer라는 녀석이 읽어들이는 메모리의 범위가 double을 상정해서 8Byte라고 한다면 p1이라는 녀석은 iNum1, iNum2가 조합된 희안한 메모리 범위를 읽어오려고 할 것입니다.
이제 감이 오시죠? 궂이 char*니 double*이니 하는 포인터 데이터 타입이 존재하는 이유는 해당 포인터 변수가 참조해야 할 데이터 범위와 형태를 제대로 알기 위해서 존재하는 겁니다.
따라서 char* 형 포인터 변수라면 이 녀석이 참조하는 주소로부터 1Byte만큼을 읽어들이면 되고, int* 형 변수라면 4Byte만큼, double*라면 8Byte만큼을 읽어들이라는 얘깁니다.
자 이제 한단계 올라갑니다.
모든 변수에는 고유주소가 할당된다고 했습니다. 포인터 변수라고 예외는 아니지요.
포인터 변수도 마찬가지로 고유 주소가 있고, 이를 이용해서 참조에 참조를 거듭하는 다차원 포인터라는 녀석이 존재합니다.
흐아~~ 이건 또 뭐야~ 라고 당황하실 수 있는데요 사실 이것도 알고보면 별거 아닙니다.
앞서 char* 라는 녀석은 이 녀석이 참조하는 메모리 주소로 부터 1Byte를 읽어들인다고 했죠?
char** 라는 녀석은 이 녀석이 참조하는 메모리 주소로부터 char* 크기만큼 읽어들여 사용하는 것 뿐 입니다. 예제를 보시죠.
*--------------------------------------------------------------------------------------*
int tmp = 77; // 일반 정수형 변수를 선언하고 임의의 수를 대입
int* ptmp = &tmp; // 정수형 포인터 변수를 선언하고 tmp의 주소를 저장
int** pptmp = &ptmp; // 정수형 2차원 포인터 변수를 선언하고 ptmp의 주소를 저장
printf( "tmp의 주소 : %d\n", &tmp );
printf( "tmp의 값 : %d\n", tmp );
printf( "\n" );
printf( "ptmp의 주소 : %d\n", &ptmp );
printf( "ptmp의 값 : %d\n", ptmp );
printf( "ptmp의 참조값 : %d\n", *ptmp );
printf( "\n" );
printf( "pptmp의 주소 : %d\n", &pptmp );
printf( "pptmp의 값 : %d\n", pptmp );
printf( "pptmp의 참조값 : %d\n", *pptmp );
printf( "\n" );
printf( "*pptmp의 주소 : %d\n", &(*pptmp) );
printf( "*pptmp의 값 : %d\n", (*pptmp) );
printf( "*pptmp의 참조값 : %d\n", *(*pptmp) );
*--------------------------------------------------------------------------------------*
결과
tmp의 주소 : 1245052
tmp의 값 : 77
ptmp의 주소 : 1245048
ptmp의 값 : 1245052
ptmp의 참조값 : 77
pptmp의 주소 : 1245044
pptmp의 값 : 1245048
pptmp의 참조값 : 1234052
*pptmp의 주소 : 1245048
*pptmp의 값 : 1245052
*pptmp의 참조값 : 77
*--------------------------------------------------------------------------------------*
먼저 tmp의 주소와 ptmp의 변수값, pptmp의 참조값을 주목해 주세요. [스터디 06]에 나왔던 예제의 내용과 거의 비슷합니다. 일반 변수의 주소값이 1차원 포인터의 변수값이고, 2차원 포인터의 참조값이 됩니다.
그리고 ptmp의 주소, 값, 참조값과 *pptmp의 주소, 값, 참조값을 비교해 보세요. 두 그룹의 값이 완전히 동일 한 것을 알 수 있습니다.
여기서 알 수 있는 것은 다차원 포인터란 몇번의 참조를 거쳐야(몇개의 포인터 연산자를 써야) 원시값에 접근이 가능한가로 요약할 수 있다는 것입니다.
앞서 메모리를 참조하는 부분에 있어서도 만약 5차원 포인터 변수를 사용했다고 하더라도
*****5차변수 = ****4차변수의 값 = 3차변수의 주소
*****5차변수 = ****4차변수 = ***3차변수의 값 = 2차변수의 주소
*****5차변수 = ****4차변수 = ***3차변수 = **2차변수의 값 = 1차변수의 주소
*****5차변수 = ****4차변수 = ***3차변수 = **2차변수 = *1차변수의 값 = 일반변수의 주소
*****5차변수 = ****4차변수 = ***3차변수 = **2차변수 = *1차변수 = 일반변수값
이런 방식의 접근에 의해 사용되어진다는 뜻 입니다.
아.. 그리고 조심하셔야 할 부분은... [&변수 == 1차포인터값] 이지만 [&&변수]니 [&&&변수]니 하는 역행접근은 절대 불가능하다는 것...(전혀 예상 못하고 있었는데.. 학교 후배녀석 중에 하나가 이걸 물어보는 바람에.. 이렇게 생각하는 사람도 있다는 걸 알았습니다 ㅡ,.ㅡ;; 그냥 참고하세요)
일단 포인터가 갖는 타입에 관계된 특성과 특징에 대해서 알아보았습니다.
다음으로는 배열과 포인터의 관계에 대해서 알아보도록 하겠습니다.
그럼 이만..
|
Hit : 8395 Date : 2011/05/01 11:28
|