본문으로 바로가기

[C] 포인터 - 2

category 개발자과정준비/C 2020. 10. 15. 14:03
반응형

포인터 변수가 가리키는 자료형의 의미

포인터 변수가 가리키는 자료형은 포인터 변수가 가리키는 메모리 공간의 해석과 연관된다.

포인터 값 자체는 정수값이지만 가리키는 자료형에 대한 정보를 가지고 있으므로 정수형 변수가 저장할 수 없다.

 

 

 

포인터 변수에 주소값을 대입할때는 형변환을 해주지 않아도 컴파일은 되지만, 컴파일러는 잠재적 위험으로 인식하고 있다. 형변환을 해줘서 잠재적 위험을 없애주자.

형변환 없이 빌드했을때 잠재적위험을 컴파일러가 감지함(좌)                                 형변환했을때 잠재적 위험을 없앴을때(우)

 

 

 

 

포인터 변수를 호출할때 *는 그 주소로 따라가라는 뜻으로 사용된다.

 

int iNum = 100;

int *p = &iNum;

을 선언해주면

 

Type  Name  Address

 int    iNum      2000(임의로)

 int*     p         1000(임의로)

심볼테이블이 생성된다.

 

int는 4바이트, 포인터는 4바이트를 차지한다.

두 변수는 메모리 주소에서 4Byte를 차지하는데, 가장 낮은 주소를 가진다.(iNum은 2000, 2001, 2002, 2003을 가지고있는데, 2000주소를 가지고있다고 표현한다.)

 

<번역작업>

1. iNum  = 100;   // int = int 이므로 iNum에 100을 대입해라.

=> 2000번지에 정수 100을 값으로 가져라.

=> (int) 2000번지 = 100;

=> (int*) 2000 = 100; 

=> *((int*) 2000) = 100;

 

즉, int iNum = 100;  을 선언하는 것은 *((int*)2000) = 100;  이라는 뜻이다.    

 

 

2. int* p = &iNum;   // (p는 int*), (&는 주소, iNum은 int형이므로 &iNum은 int* 이므로) int* = int* 이므로 대입할 수 있다.

=> p = 2000;

=> 1000번지 = 2000;

=> (int*)1000 = 2000;

=> *((int*)1000) = 2000;

 

즉, int *p = &iNum; 을 선언하는 것은 *((int*)1000) = 2000;  이라는 뜻이다. 

 

 

 

만약에 iNum = 500; 을 선언한다고하면 이는 *p = 500; 과 같다.

iNum = 500;

=> *((int*) 2000) = 500;

 

*p = 500;    // 이때 이 구문은 포인터를 사용한 값의 수정이라고 한다.

=> *((int*)2000) = 500;

 

 

#include <stdio.h>

int main() {
	//문자형 포인터 변수가 int형 변수의 값을 출력하는 프로그램
	char ch, * pch;
	int iNum, * piNum;
	float fNum, * pfNum;

	ch = 'a';
	iNum = 0x1314;
	fNum = 25.3;

	pch = &ch;
	piNum = &iNum;
	pfNum = &fNum;

	printf("ch  : %5c,        *pch : %5c\n", ch, *pch);
	printf("iNum : %5x,      *piNum : %5x\n", iNum, *piNum);
	printf("fNum : %5.2f,      *pfNum : %5.2f\n\n", fNum, *pfNum);
    
	pch = (char*)piNum;  // 자료형이 다르므로 형변환을 해준다
	printf("pch  : %p,     *pch : %x\n", pch, *pch);
	pch++;
	printf("pch  : %p,     *pch : %x\n", pch, *pch);

	return 0;
}

출력문의 위의 3줄은 각 변수의 값과 *(포인터변수)의 값은 똑같이 출력되는 것을 확인할 수 있다.

 

 

 

디버그 모드로 포인터 변수들의 값이 주소가 저장되었는지 확인해보자.

 

포인터 변수에 각 변수의 주소값을 대입했을때, printf로 출력하면 각각 똑같은 값이 출력되는 것을 볼 수 있다.

 

 

 

pch에 piNum값을 대입했을때이다. piNum은 int*형 변수이므로 char*로 형변환을 통해 대입해야한다.

char*은 1Byte를 차지하므로 piNum 값중에 c0 가 pch에 대입된다. 이때 c0가 가리키는 주소값은 14이므로 

printf로 출력할때는 14가 출력된다.

 

 

 

 

pch++; 를 선언했을때, pch에서 ++을 해줬으므로 c0 -> c1이 되고, c1이 가리키는 주소의 값은 13이 되므로 13이 출력된다.

반응형