게임 개발을 목표로 하기에 상용 엔진 중 언리얼 엔진은 C++을 기반으로 사용하므로 언제 사용하게 될지 모르니
예전에 C++을 살짝 맛만 봤을 때 던졌던 포인터를 한번 짚고 가보도록 하겠습니다.
포인터
데이터의 메모리 주소를 가리키는 것
그나마 최근에 C를 사용했기에 친숙한 언어로 써보겠습니다.
#include <stdio.h>
int p = 10;
void Main()
{
ExPointer(p);
printf(p);
}
void ExPointer(int p)
{
p += 1;
printf(p);
}
실행 결과는
ExPointer(p); 내의 printf(p) = 11
ExPointer(p); 다음의 printf(p) = 10
으로 나옵니다.
왜냐하면,
int p = 10; 으로 선언한 변수 p
void ExPointer(int p) 의 매개변수 p는
글로벌 변수 p의 값을 복사하여
내부에서 연산만 하고 끝났기에
글로벌 변수 p의 값은 변하지 않은 것입니다.
이를 포인터를 사용하여 유의미한 결과로 바꾸면
#include <stdio.h>
int p = 10;
void Main()
{
ExPointer(&p);
printf(p);
}
void ExPointer(int *p)
{
// 여기서 *p는 p에 담긴 값 10
*p += 1;
printf(p);
}
함수를 선언할 때, 매개변수 *p
함수의 매개변수로 주소값을 받음을 의미
함수를 호출할 때,
&p = p의 값이 담긴 메모리 공간의 주소 값
메모리 주소를 매개로 호출하며
함수에서 해당 메모리에 직접 접근하여 값을 가져오고 쓸 수 있게 됩니다.
아래와 같이 포인터를 선언하고 주소값을 넣어두고 써도 됩니다.
#include <stdio.h>
int p = 10;
// 포인터의 자료형은 무엇을 써도 됨. p의 주소값으로 초기화
double *q = &p;
void Main()
{
ExPointer(q);
printf(p);
}
void ExPointer(int *p)
{
*p += 1;
printf(p);
}
포인터를 사용한 실행 결과들은
p의 주소에 접근해 값을 직접 바꾸었기에
ExPointer(p); 내의 printf(p) = 11
ExPointer(p); 다음의 printf(p) = 11
순으로 나옵니다.
번외)
#include <stdio.h>
int p = 10;
void Main()
{
ExPointer();
printf(p);
}
void ExPointer()
{
p += 1;
printf(p);
}
공부를 진행하다 의문이 들었습니다.
바로 위 코드처럼 포인터를 사용하지 않고도 쉽게 동일한 역할을 수행하는 코드를 작성할 수 있는데
프로그래밍 입문 방지턱으로 아주 성벽을 쌓기로 유명한 포인터는 대체 왜 쓰는 것인지?
어느 자료들을 봐도 그저 "메모리에 직접 접근할 수 있다" 라고만 두루뭉술하게 적혀 있어서 그게 왜 좋은지에 대한 감이 전혀 오지 않습니다.
그래서 왜 좋은지에 대해
최근에 자료구조 강의에서 배운 배운 얕은 지식으로라도
그 이유를 고찰해 보는 시간을 가져봤습니다.
아래는 비전공자의 시각으로 본 주관적인 해석이기에
100% 신뢰하지 말고 쓰는 이유가 이건가 짐작하는 정도로만 봐줬으면 합니다.
방금 작성한 단순한 코드의 동작을 살펴본다면,
ExPointer() 내부의 p += 1; 를 수행할 때
p로부터 변수의 주소값 가져오는 과정
>> p의 주소로 찾아가기
>> 담긴 값에 1을 더하기
포인터를 사용한다면
ExPointer(int q) 함수를 호출할 때
과정이 하나 줄어들게 됩니다.
p의 주소(q)로 찾아가기
>> 담긴 값에 1을 더하기
프로그램의 규모가 커져서
해당 함수를 아주 많은 n회 호출한다고 하면
주소값을 1번만 가져와서 기억해두고,
데이터의 주소를 찾는 과정(찾는 데걸리는 시간 = c)을 n회 줄어들어서
줄어드는 시간 대략적으로 c(n-1)
복잡도를 O(n)만큼 줄일 수 있게 됩니다.
위의 예제는 아주 단순한 함수라 O(n)이지만
예를 들어,
함수 내에서 반복문을 쓰고
그 내부에 데이터의 주소를 찾는 과정이 있다면
더 높은 차원의 복잡도도 줄일 수 있기에
구조에 따라 더 큰 수행 시간을 줄일 수 있을 것이라 봅니다.
이렇게
프로그램의 성능 향상에 도움이 되므로 배우고 쓴다고 결론을 내었습니다.
다른 장점들이 더 있을지는 모르겠지만 지식의 한계로 여기까지인 것 같습니다.
하지만 이후의 사용자 친화적인 언어들은
프로그래밍 입문 장벽을 낮추기
잘못된 주소에 접근하여 문제가 생기는 실수를 방지
기기 성능의 발전으로 줄어든 성능에 대한 보완을 할 수 있음
등
퍼포먼스의 고점을 낮추더라도 얻을 수 있는 장점들이 크다고 여겨
포인터의 사용을 막았다고 생각해 볼 수 있었습니다.
C# : 보안을 이유로 포인터를 쓰지 않는 것을 권장
자바 : 참조(Reference)를 사용
파이썬 : 사용자가 직접 메모리에 접근하지 못하도록
구조부터가 다른데,
변수를 메모리 공간에 넣는 것이 아니라
값을 각각 메모리 공간에 넣어두고
각 변수의 값을 바꾸려 하면 해당 값의 메모리 공간의 주소를 참조
실제 사용은 a=1, b=2 이런 식으로 아주 간결하게 사용
'기타' 카테고리의 다른 글
시프트+딜리트로 실수로 파일을 삭제했을 때 무료 복구 방법 (0) | 2025.03.29 |
---|---|
티스토리 다크 모드 무료 스킨 추천 및 적용 (0) | 2025.03.02 |
C) 하노이의 탑 실행창에서 게임으로 즐기기 (exe, 소스 코드 첨부) (0) | 2025.03.01 |
gif 배너 만들 때 사용한 툴 정리 (0) | 2024.03.14 |