2010년/3월

3월22일 포인터와 스택구조

뽀얀햄스터 2010. 3. 22. 12:40


#include<stdio.h>
int
 main()
{
  //첫번째~
  int iA;
  int *iP;
  char *cP;
  char cB;

  iA=0x12345678;
  cB=0xAB;
  iP=&iA;
  cP=&cB;

  // 두번째~
  cB=iA;
  *iP=0xFA;
  *cP=0x1234;
  cP= (char *)iP;
  
  //세번째~
  *cP=0x12345678//틀린부분

  //네 번째~

  ++cP;     //12FF41 
  *cP=0x123456;
  
  
  //다 섯 번째~
  *((unsigned short *)(0x12FF42))=0x1234;

  //여 섯 번째~
  iA=(int)&cP;
  --iA;
  //일 곱 번째~ 
  iP=(int *)iA;
  //여덟 번째~ 
  *iP=0xABCDEF00;

  //마무리
  iP=0;
  cP=0;
  


  return 0;
}

-심볼 테이블-



위의 프로그램 소스를  심볼 테이블로 변경 시킨경우이다.  여기서 중요한점은  int * 과 char *로 포인터변수의  자료형이 틀린경우이다.

-첫번째-
  int iA;
  int *iP;
  char *cP;
  char cB;

  iA=0x12345678;
  cB=0xAB;
  iP=&iA;
  cP=&cB;



일단 변수를 선언하고 iA에 값이 12345678이 little endian으로 들어가기때문에  뒤집어서 들어가는것을 볼수 있다. 그리고cB에와 cP iP도 역시  제대로 들어가는걸 볼 수있다.






-두번째-
  cB=iA;
  *iP=0xFA;
  *cP=0x1234;
  cP= (char *)iP;

cBiA를 넣게 되면 묵시적 캐스팅으로 인해서 먼저 12345678에서  78만 들어가게 된다. 그리고 iP를 포인터연산자를 사용할경우  FA에 들어가게 되고 cP에는 char형이기대문에 12가 짤리고 34만 들어가게된다. 그리고 iP에 있는값을 cP에 넣으므로 cP와 iP의 값은 같다. 그리고 (char *)한이유는 int * 와 char * 형이 틀리기때문이다.


-세번째-

*cP=0x12345678
코드는 아주 간단하게 되어있다. cP의 포인터연산자  실행이다 하지만  여기서 cP는 char * 형이다 그래서  입력할경우  자리는 iA의 int형이지만 char라서  입력이 1바이트만 된다 12345678중에 마지막 78만 입력된다.
 




-네 번째-
++cP;     //12FF41 

*cP=0x123456;


cP의 값을 1을 증가 시키고 넣었다. 그러면 cP의 12FF40 -> 12FF41로 일이 증가가  된다 그리고  포인터연산자로cP안의 주소값에 123456을  넗게 된다 하지만 cPchar *라서 1바이트인 마지막값이 56이 들어가게 되고 12FF41자리는  지금 빨간 숫자가 들어간 곳에 56이 들어가게 된다. 


 -다 섯 번째-
  *((unsigned short *)(0x12FF42))=0x1234;


unsigned short 0x12FF42 번지에 1234를 넣어라는 뜻이다. (unsigned short은 2바이트형이다 0x12FF42번이후 2바이트이므로 0x12FF43까지 0x1234가 다들어가게 된다.  
여기서  중요한점은 포인터함수에서 주소값을 주게 되면 마음대로 이동하고 값을 바꿀수있다.~!!!!!!



-여 섯 번째-
  iA=(int)&cP;
  --iA;

cp의 주소(0012FF38)를 iA  넣는다. 그리고 -1을 뺀후 넣게 되면 0012FF37이  iA에 들어가된다. 여기서 중요한점은 cP는 char * 이기때문에 (int)로 캐스팅을 해줘야한다. 포인터는 특별하게 생각하기때문에 어렵다. 하지만 point는 int랑 같다고 생각하면된다 단지 포인터연산자(*)사용될때와  들어가는값이 주소를 넣다는다는것이 틀린점이다.


-일 곱 번째-
  iP=(int *)iA;
iA에 값을 iP에 대입 시키는것이다. iP포인터자료형(int *)이고 iAint자료형이다 그래서  (int *)를 통해서 캐스팅하고 값을 맞춰준다.







-여덟 번째- 
  *iP=0xABCDEF00;

iP값은  0012FF37이다. 즉 0012FF37자리에 0xABCDEF00을 넣게된다. 그래서 12FF37자리안에  00을 찍고 EF CD AB를 차례대로 넣게 된다. (빨간숫자가 들어가게 되는것이다.)







마무리는 cP와 iP자리에 전부 0이 들어가고 끝이 난다.
여기서 소스프로그램을 보고  포인터의 장점과 단점  그리고 자료형따른 출력과 입력을 알수 있다.


  printf("메인함수주소0x%08X\n",&main);
  printf("printf함수주소0x%08X\n",&printf);
  printf("scanf함수주소 0x%08X\n",&scanf);

이렇게 함수들의 메모리 주소값을 알수  있다 그리고 이렇게  중요한 값이 저장된 메모리 영역Code 또는 Text라고 불린다. 

cp=main;
cp에  main을 넣을경우  char  * 자료형에 맞지않다고 한다 근데 웃긴것은 main함수의 자료형int(__cdecl  *)()이다  포인터자료형인데 처음보는것이다 함수포인터로 나중에  다시 배우게 될내용이다. 메모리에서 구역마다  사용하는 곳이 다틀리다  아쉽게도 main과 같은경우는 어쩔수없이 윈도우가 막아둔다. 이는  일반사용자가 건들경우  치명적인 결과가 나오기때문에read는 가능하나 write는 불가능하다.