1619, 1/81 회원가입  로그인  
   sihun1113
   [C기초] 07 - 포인터의 타입과 접근법

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