본문 바로가기

C언어

C언어_포인터와 주소값

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char* argv[])
{
	   int a = 0x12345678;
	   int *ptr = &a;


	   puts("\n Test 1. ===========================");
	   fprintf(stdout, "Data of %10s: %8x\n", "int ptr", *ptr);
	   fprintf(stdout, "Data of %10s: %8x\n", "short ptr", *(short *)ptr);
	   fprintf(stdout, "Data of %10s: %8x\n", "char ptr", *(char *)ptr);

	   puts("\n Test 2. ===========================");
	   char *dy_chptr = (char *)ptr;
	   // (char *)으로 type casting한 ptr
	   // chptr 값 바뀜

	   fprintf(stdout, "data(0): %10x\n", *dy_chptr);
	   fprintf(stdout, "data(1): %10x\n", *(++dy_chptr));
	   fprintf(stdout, "data(2): %10x\n", *(++dy_chptr));
	   fprintf(stdout, "data(3): %10x\n", *(++dy_chptr));

	   puts("\n Test 3. ===========================");
	   char *fix_chptr = (char *)ptr;
	   // (char *)으로 type castring한 ptr
	   // chptr 값 고정

	   fprintf(stdout, "data(3): %10x\n", *(fix_chptr+3));
	   fprintf(stdout, "data(2): %10x\n", *(fix_chptr+2));
	   fprintf(stdout, "data(1): %10x\n", *(fix_chptr+1));
	   fprintf(stdout, "data(0): %10x\n", *fix_chptr);
	   fprintf(stdout, "data(-1): %10x\n", *(fix_chptr-1));
	   fprintf(stdout, "data(-2): %10x\n", *(fix_chptr-2));
	   fprintf(stdout, "data(-3): %10x\n", *(fix_chptr-3));


	   puts("\n Test 4. ===========================");

	   fprintf(stdout, "Address of (%12s): %8x\n", "a", &a);
	   fprintf(stdout, "Address of (%12s): %8x\n", "ptr", &ptr);
	   fprintf(stdout, "Address of (%12s): %8x\n", "dy_chptr", &dy_chptr);
	   fprintf(stdout, "Address of (%12s): %8x\n", "fix_chptr", &fix_chptr);

	   puts("\n Test 5. ===========================");
	   int b=1;
	   int c=5;
	   int d=6;
	   int *ptr1 = &b;
	   int *ptr2 = &c;
	   int *ptr3 = &d;


	   fprintf(stdout, "Address of (%12s): %8x\n", "ptr2+1", ptr2+1);
	   fprintf(stdout, "Address of (%12s): %8x\n", "ptr2", ptr2);
	   fprintf(stdout, "Address of (%12s): %8x\n", "ptr2-1", ptr2-1);



	   fprintf(stdout, "data(ptr2+1): %10x\n", *(ptr2+1));
	   fprintf(stdout, "data(ptr2): %10x\n", *ptr2);
	   fprintf(stdout, "data(ptr2-1): %10x\n", *(ptr2-1));

	   return 0;
}

#pragma GCC diagnostic pop

-Test1 

원본 데이터 변수 a에 대해 int형 포인터 ptr 을 선언한 후, ptr에 대해 (short *) 와 (char *) 로
type-casting 

0x12345678 데이터에 대해 포인터로 참조 후 short형 포인터로 type-casting 후 해당 포인터를 역참조를 하였을 때 (short *)ptr이 LSB로부터 2byte의 데이터만 참조하는 것을 알 수 있었다.
=> 결과 값:  0x5678

 

ptr에 대해 char 형 포인터로 type-casting 후 역참조를 하였을 때는 (char*)ptr이 LSB로부터 1byte의 데이터만 참조하는 것을 알 수 있었다.
=> 결과 값: 0x78

-결과

-Test2,3

 

테스트 2와 테스트 3은 ptr을 (char *)로 type-casting한 이후 포인터 연산에 대해 테스트해보았다.

Shell prompt에서 작동하는 커서 작동방식이나 c언어 fseek 함수에서의 파일 포인터 값 변경하는 것에 이용될 것 같다는 느낌이 들었다.

dy_chptr 포인터의 경우, 포인터 값을 1씩 늘릴 때마다 (=> ++dy_chptr) LSB로부터 offset 값이1byte씩 늘어나며

fix_chptr 포인터의 경우는 offset을 고정시키고, (fix_chptr+3)와 같이 연산 값을 확인함으로써 상대적 주소에 대한 값을 확인해보았는 데
예상대로 4byte인 0x12345678에 대해 fix_chptr+3 은 0x12를, fix_chptr+2는 0x34 … 값을 출력함을 알 수 있었다.

 

ptr에 대해 char 형 포인터로 type-casting 후 역참조를 하였을 때는 (char*)ptr이 LSB로부터 1byte의 데이터만 참조하는 것을 알 수 있었다.
=> 결과 값: 0x78

-결과

-Test4 => 메모리 상에 어떻게 저장되는지 확인 모두 4byte size이기 때문에 다음과 같이 메모리 스택 영역에 높은 주소부터 낮은 주소까지 차례대로 올려져 있는 것을 확인할 수 있었다.