본문 바로가기

언어/C, C++, C#

[ C ] 포인터

포인터 변수 : 메모리의 주소 값을 저장하기 위한 변수

int main(void){

int num=7;
int * pnum;
pnum = #

}

포인터 변수 pnum이 int형 변수 num을 가리킨다

 

 

 

포인터 선언하는 방법 

 

type * ptr ( 타입 + 변수 명 )

int main(void)
{

int num1 = 5;
double * pnum1 = &num1;

}

num1의 변수 선언 타입 값과 포인터 선언 타입 값이 다르기에 오류가 발생한다

 

int main(void)
{

int num1 = 100;
int num2 = 100;

int * pnum = &num1;      -> pnum은 num1의 주소 값을 가르킨다
(*pnum) += 30            -> num1 대상인 포인터 값을 30 증가 시킨다
printf("%d" , *pnum);    -> 130

int * pnum = &num2;      -> pnum은 num2의 주소 값을 가르킨다
(*pnum) -= 30            -> num2 대상인 포인터 값을 30 감소 시킨다
printf("%d" , *pnum);    -> 70

}

포인터가 주소값 누구를 가르키냐에 따라 달라진다

 

 

 

포인터 형을 쓰는 이유

 

:포인터 기반의 메모리 접근기준을 마련하기 위함

 

 

 

배열에서의 포인터

 

int main(void)
{

int arr[3] = { 11 , 22 , 33 };
int * ptr = arr;
printf( "%d %d %d", *ptr , *(ptr + 1), *(ptr + 2) ) -> 11 22 33

printf("%d ", *ptr );  -> 11
ptr++;
printf("%d ", *ptr );  -> 22
ptr--;
printf("%d " )         -> 11
}

포인터 주소 값을 증가시키면 가리키는 배열 주소 값도 증가한다

 

 

 

함수에서의 포인터

 

포인터 쓰지 않을 때 swap는 파라미터 값을 복사하여 사용한다

 

void swap(int *ptr1, int *ptr2) 
{

int temp = *ptr1;
*ptr1 = *ptr2;
*ptr2 = temp; ->둘 주소 자리 바꿈

}

int main(void)
{

int num1 = 10;
int num2 = 20;

printf("num1 num2: %d %d", num1, num2);  -> 10 20
swap(&num1, &num2);
printf("num1 num2: %d %d", num1, num2);  -> 20 10
return 0;

}

포인터를 사용한 swap은 파라미터 값을 복사하지 않고 주소 값을 가르켜 사용한다

 

 

 

포인터의 포인터

 

 

int main(void)
{

double num = 3.14;
double *ptr = #
double **dptr = &ptr;
double *ptr2;

printf("%9p %9p", ptr, *dptr);   -> num의 주소값 , num의 주소값
printf("%9g %9g", num, **dptr);  -> 3.14 , 3.14
ptr2 = *dptr;                    -> ptr의 주소값을 가르킴 
*ptr2 = 10.99;                   -> ptr의 주소값인 num에 10.99가 들어감
printf("%9p %9p", num, **dptr);  -> 10.99 , 10.99
return 0;

}

ptr2가 ptr의 주소값을 가르키는데 ptr은 num의 주소 값을 가르키므로 최종적으로 num을 가르키고있다

 

 

 

이중 포인터 형을 쓰는 이유

 

void SwapError(int *p1, int *p2)        -> num1, num2의 주소값이 아닌 담긴 데이터 값을 가져옴
{

int * temp = p1;
p1 = p2;
p2 = temp;

}

void SwapIntPtr(int **dp1, int **dp2)   -> ptr1, ptr2이 가르키는 num1, num2 주소값 가져옴
{

int * temp = *dp1;
*dp1 = *dp2;
*dp2 = temp;

}

int main(void)
{

int num1 = 10, num2 = 20;
int *ptr1, *ptr2;
ptr1 = &num1, ptr2 = &num2;
printf("*ptr1, *ptr2: %d %d" *ptr1, *ptr2);

SwapIntPtr(ptr1& , ptr2&);
printf("*ptr1, *ptr2: %d %d" *ptr1, *ptr2);

return 0;

}

SwapError 함수는 주소 값이 아닌 데이터 값을 참조하여 데이터 swap가 이뤄지지 않는다

반면 SwapIntPtr함수는 num 주소값을 참조하여 결과적으로 데이터 swap가 이뤄진다

 

 

'언어 > C, C++, C#' 카테고리의 다른 글

[ C# ] 람다함수  (0) 2022.07.03
[ C# ] main함수 여러 개일 때 컴파일  (0) 2022.07.02
[ C ] Stream  (0) 2022.06.02
[ C ] 포인터2  (0) 2022.05.30
[ C# ] 닷넷 예제 공부  (0) 2021.12.16