포인터란
메모리 공간을 가리키는 주솟값을 뜻합니다.
포인터 변수란
메모리 공간을 가리키는 주솟값을 저장하는 공간입니다.
/*별표의 위치는 상관없다 */
int* p1;
char * p2;
void *p3;
포인터 변수의 저장공간은 자료형에 상관없이
컴퓨터 os 주소체계를 따르는데요
32bit 운영체제 이면 포인터 변수의 공간이 4바이트고
64bit 운영체제 면 8바이트입니다.
포인터 변수를 선언할 때 자료형이 각각 정해져 있는 이유는
자료형 저장 크기만큼 읽어오기 위해서이며
자료형마다 저장되는 자료가 쓰이는 형식이 틀린 이유이기도 합니다.
자료형의 크기만 고려했다면 가장 큰 자료형 포인터 변수로 만들면 되는데
자료형마다 저장되는 자료가 메모리에 쓰이는 형식이 다르기 때문에 그렇습니다.
void형은 형태가 정해져 있지 않는 자료형인데
이 자료형을 사용할때는 캐스팅을 이용해서 사용할 자료형을 지정하면 사용할 수 있습니다.
주소 연산자 / 역참조 연산자
#include <stdio.h>
int main()
{
int a = 1;
int b = 2;
char c = 'z';
int* pA;
int* pB;
char* pC;
pA = &a; //포인터 변수 pA에 a의 주소를 담는다.
pB = &b;
pC = &c;
printf("pA : 0x%008x\n", pA); //pA에는 a의 주소값이 담겨있다.
printf("pB : 0x%008x\n", pB);
printf("pC : 0x%008x\n", pC);
printf("pA : %d\n", *pA);// 역참조 연산자로 pA가 가리키고 있는 a의 값을 확인한다.
printf("pB : %d\n", *pB);
printf("pC : %c\n", *pC);
return 0;
}
포인터에서 헷갈리는 부분은
왜 사용하는지에 대한 의문이 계속 남아 있기 때문에 헷갈립니다.
해당 함수 안에서 만든 변수가 내부가 아닌
외부의 함수나 외부의 공간에서 사용할 수 있고
자료구조에서 포인터가 쓰이기 때문인데요
일단은 외부 함수에서 쓰기 위해 포인터를 쓴다는 점을 생각을 해 두시고
하나씩 확인해보겠습니다.
int a = 1;
int b = 2;
char c = 'z';
int* pA;
int* pB;
char* pC;
일반 변수를 선언 초기화하고
해당 변수의 주소를 담을 포인터 변수를 생성합니다.
pA = &a; //a의 주소가 1000이라면 pA에는 1000
pB = &b;
pC = &c;
포인터 변수에 각각 일반 변수의 주솟값을 담습니다.
이 순간 각각의 포인트 변수에는 해당 일반 변수의 주솟값이 들어가 있습니다.
printf("pA : 0x%008x\n", pA); //pA에는 a의 주소값이 담겨있다.
printf("pB : 0x%008x\n", pB); //%x는 16진수 출력 서식문자
printf("pC : 0x%008x\n", pC); //%008은 출력되는값을 8자리로 마추고 빈자리는 0으로 채움
pA에는 a의 주솟값 1000이 들어가 있습니다.
그래서 출력하면 a의 주솟값이 출력이 됩니다.
printf("pA : %d\n", *pA);// 역참조 연산자로 pA가 가리키고 있는 a의 값을 확인한다.
printf("pB : %d\n", *pB);
printf("pC : %c\n", *pC);
선언할 때의 *이 아닌 포인터 변수 앞에 붙은 *은 역참조 연산자입니다.
역참조 연산자는 주소가 가리키고 있는 값을 의미합니다.
pA가 가리키고 있는 a의 주소(1000)의 값 1입니다.
다중 포인터
int a;
int* pA;
int** ppA;
int*** pppA;
pA = &a;
ppA = &pA;
pppA = &ppA;
보통은 **까지만 사용되고 ***는 거의 보기 어렵다고 보시면 됩니다.
int* pA는 일반 변수 a의 주솟값을 담습니다.
int** ppA는 포인터 변수 pA의 주솟값을 담습니다.
int*** pppA는 포인터 변수 ppA의 주솟값을 담습니다.
결국 모두 일반 변수 a를 가리키고 있는 형태가 나옵니다.
다중 포인터는 아래 소스가 이해가 되면 된다고 보시면 됩니다.
#include <stdio.h>
void SwapIntPtr(int **p1, int **p2)
{
int * temp = *p1;
*p1 = *p2;
*p2 = temp;
}
int main(void)
{
int num1 = 10, num2 = 20;
int *ptr1, *ptr2;
ptr1 = &num1, ptr2 = &num2;
printf("*ptr1, *ptr2: %d %d \n", *ptr1, *ptr2);
SwapIntPtr(&ptr1, &ptr2);
printf("*ptr1, *ptr2: %d %d \n", *ptr1, *ptr2);
return 0;
}
위 소스의 전제조건은
ptr1의 "주소" ptr2의 "주소"를 변경하여
값을 스왑하는 형태로 되어있습니다.
'컴퓨터 프로그래밍 > C' 카테고리의 다른 글
C언어 main 함수에게 인자 전달(argc, argv) (0) | 2019.07.23 |
---|---|
C언어 1차원 배열 / 문자열 배열 / 배열(포인터 연산) (0) | 2019.07.23 |
C언어 Call by Value / Call by Address (0) | 2019.07.23 |
C언어 함수 (0) | 2019.07.23 |
C언어 파일 입출력 (0) | 2019.07.23 |