포인터 변수가 가리키는 자료형의 의미
포인터 변수가 가리키는 자료형은 포인터 변수가 가리키는 메모리 공간의 해석과 연관된다.
포인터 값 자체는 정수값이지만 가리키는 자료형에 대한 정보를 가지고 있으므로 정수형 변수가 저장할 수 없다.
포인터 변수에 주소값을 대입할때는 형변환을 해주지 않아도 컴파일은 되지만, 컴파일러는 잠재적 위험으로 인식하고 있다. 형변환을 해줘서 잠재적 위험을 없애주자.
포인터 변수를 호출할때 *는 그 주소로 따라가라는 뜻으로 사용된다.
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이 출력된다.
'개발자과정준비 > C' 카테고리의 다른 글
[C] 포인터 - 4 (실수부 포인터) (0) | 2020.10.21 |
---|---|
[C] 포인터 - 3 (포인터 초기화, 포인터 연산) (0) | 2020.10.20 |
[C] 포인터 - 1 (0) | 2020.10.14 |
[C] 반복문을 활용해서 구구단 출력 (0) | 2020.10.13 |
[C] Scanf 런타임오류 해결 방법 (0) | 2020.10.10 |