1. 포인터 변수

C언어에서 포인터는 메모리 주소를 저장하는 변수로 다른 변수에 사용하고 있는 메모리의 주소를 가리키는 변수다.

 

이것을 사용하면 메모리에 저장된 데이터를 직접 조작할 수 있는데

이를 통해 call by reference를 할 수 있다.

#include<stdio.h>	// C의 헤더파일

int main()
{
	const int num = 10;				// 상수화할 때는 초기화를 동시에 해주어야 한다, 예를 들어 const int num; 이렇게 적으면 아무것도 할 수 없는 쓰레기 값이 되어버린다.
	printf("num: %d\n", num);

	int* p = &num;					// 주소를 저장할 수 있는 포인터변수, &(주소연산자), 여기서 *는 연산자가 아닌 기호로 그저 포인터변수임을 나타낸다.
	printf("p에 저장된 값:  %p\n", p);		// 주소를 저장할 때는 앞에 &를 붙여줘야 한다.
	printf("p가 참조하는 값:  %d\n", *p);		// 여기서 p에 저장되는 값은 렘의 주소값이며 p가 참조하는 값은 10이다.

	*p = 100;					// 여기서 나온 *은 간접 참조연산자다. 포인터는 주소를 저장하므로
	printf("p가 가리키는 곳의 데이터 값:  %d\n", *p);	// 여기서 p에 저장되는 값은 렘의 주소값이며 p가 참조하는 값은 10이다.
	printf("p가 참조하는 값:  %d\n", num);		// 여기서 p에 저장되는 값은 렘의 주소값이며 p가 참조하는 값은 10이다.
	printf("num: %d\n", num);

	int num1 = 100;
	int num2 = 200;
	const int* pa = &num1;
	printf("pa: %p\n", pa);
	pa = &num2;
	printf("변경 후 pa: %p\n", pa);

	int* const pb = &num1;			// 포인터 변수의 상수화
	*pb = 70;

	return 0;
}
// 출력값
num: 10
p에 저장된 값:  00000068006FF8C4
p가 참조하는 값:  10
p가 가리키는 곳의 데이터 값:  100
p가 참조하는 값:  100
num: 100
pa: 00000068006FF904
변경 후 pa: 00000068006FF924

 

최초 num 값은 10이고

p에는 num이 저장된 메모리 주소값이 저장된다.

이때, p의 값을 100으로 바꾸어주자 num의 값이 100으로 바뀌었다.

 

이는 별다른 절차 없이 메모리 주소에 직접 접근하기 때문에 메모리를 직접 관리할 수 있다는 이점이 있으며

이러한 특성상 성능도 더 빨라진다는 장점이 있다.

다만 메모리 구조에 대한 높은 이해를 필요로 하며 잘 못 사용하면 이전까진 경험해보지 못한 새로운 문제와 직면해야 하기 때문에 난이도가 상당히 높다.

 

 

 

2. call by reference

포인터 함수를 통해, 저장된 변수를 직접 접근하여 수정할 수 있는데 이를 call by reference라 한다.

 

아래 코드는 call by value 방식이다.

void swap(int n1, int n2)
{
	int temp;
	temp = n1;
	n1 = n2;
	n2 = temp;
	printf("호출 중 n1: %d \t n2: %d\n", n1, n2);
}

int main()
{
	int n1 = 10, n2 = 20;
    
	printf("호출 전 n1: %d \t n2: %d \n", n1, n2);
	swap(n1, n2);
	printf("호출 후 n1: %d \t n2: %d \n", n1, n2);

	return 0;
}
//출력결과
호출 전 n1: 10   n2: 20
호출 중 n1: 20   n2: 10
호출 후 n1: 10   n2: 20

보시다시피 함수 내에서는 값이 바뀌었으나 main함수에서는 값이 바뀌지 않았다.

이는 main의 값이 swap에서 복사되어 실행되었으므로 어디까지나 swap내의 값이 바뀐 것이지

main의 값이 바뀐 것이 아니기 때문이다.

 

이번엔 call by reference를 해보자

void swap(int* pn1, int* pn2)
{
	int temp;
	temp = *pn1;
	*pn1 = *pn2;
	*pn2 = temp;
	//printf("호출 중 n1: %d \t n2: %d\n", n1, n2);
}

int main()
{
	int n1 = 10, n2 = 20;

	printf("호출 전 n1: %d \t n2: %d \n", n1, n2);

	swap(&n1, &n2);
	printf("호출 후 n1: %d \t n2: %d \n", n1, n2);

	return 0;
}
//출력결과
호출 전 n1: 10   n2: 20
호출 후 n1: 20   n2: 10

이번엔 swap에서 바뀐 값이 main에도 적용되어 있는 것을 알 수 있다.

 

이는 n1과 n2가 저장된 데이터 주소의 값을 받아와서 swap에서 해당 주소의 값을 바꾼 것이기 때문에

값의 변화가 main에도 그대로 적용된 것이다.

 

+ Recent posts