[Basic C++] #58_포인터, 배열과 포인터, 포인터 연산
C++의 "포인터"에 대해 알아보겠습니다.
"전문가를 위한 C"의 22 항목, "효과적인 메모리 관리"에 해당하는 내용입니다.
포인터 개념
1. 포인터?
포인터는 단순히 메모리 위치를 계산하는 주 솟값입니다.
2. "*"를 활용한 역 참조
"*" 연산자를 활용하면 포인터를 역 참조할 수 있습니다. 여기서 역 참조란 단순히 포인터가 가리키는 메모리 주소에 들어있는 값을 가져올 수 있습니다.
3. "&"를 활용한 참조
"&" 연산자를 활용하면 어떤 값이 저장되어 있는 메모리의 주솟값을 가져옵니다. 보통 포인터 변수에 "&a" 값을 넣어줌으로써 "a"라는 변수의 메모리 주소 값을 넘겨줍니다.
배열과 포인터
1. 배열 == 포인터, but ALL 포인터!= 배열
int arr[10];
int* arrPtr = arr;
// arrPtr을 통해 기존의 arr[10] 배열에 접근
arrPtr[4] = 5;
int* ptr = new int;
cout << ptr[1] << endl; // ??? 무슨 값이 나올지 모름
1. 배열 == 포인터?
스택에 할당된 배열은 포인터를 통해 접근이 가능합니다. 배열 변수의 이름은 단순히 배열의 0번째 항목을 가리키는 포인터를 의미합니다. 다만, 모든 포인터가 배열은 아닙니다!
함수 포인터
1. 타입 에일리어스 (using)
using MatchFcn = bool(*)(int, int);
void findMatches(int values[], int values2[] size_t valuesSize, MatchFcn someFunc)
{
for(size_t i = 0; i < valuesSize; i++)
{
if(someFunc(values[i], values[i]) == true)
cout << "Match Found At Position: " << i << '\n';
}
}
1. 타입 에일리어스를 활용한 함수 포인터
C++에서는 함수를 데이터처럼 사용할 수 있습니다. 다시 말해, 함수의 포인터를 얻어 마치 변수처럼 이용할 수 있습니다. 타입 에일리어스를 활용해 함수 포인터를 생성할 수 있으며, 해당 함수의 속성에 합치되는 함수 타입을 정의하고 이름을 부여하죠. "MatchFcn" 타입은 "bool"형을 리턴하고, 두 개의 "int" 타입 파라미터를 가지는 함수 포인터를 표현합니다!
2. 함수의 주소 값
bool someFunc2 (int val1, int val2)
{
return val1 == val2;
}
int arr1[5] = {1, 2, 3, 4, 5};
int arr2[5] = {4, 5, 6, 7, 8};
int arrSize = sizeof(arr1) / sizeof(int);
// 함수 명 혹은 & 연산자를 통해 주소 값을 인자로 넘겨줍니다.
findMatches( arr1, arr2, arrSize, &someFunc2 );
알다시피, MatchFnc의 타입은 bool 형을 리턴하며, 두 개의 int 타입의 인자를 받습니다. 우리가 작성한 "someFunc2" 함수는 MatchFnc 타입과 합치되어 "findMatches" 함수의 세 번째 인자로 넘겨줄 수 있습니다.
이때, "someFunc2" 함수명 그대로를 넘겨주어도 무방합니다.
클래스 메서드 + 클래스 데이터 멤버의 포인터
1. 클래스 메서드의 포인터
classA myClass = classA(123);
// 포인터 초기화
double(classA::*mthPtr) () const = &myClassA::getValue;
// 클래스 메서드 포인터의 호출
cout << (myClass.*mthPtr)() << endl;
C++에서 특정 클래스의 메서드 혹은 데이터 멤버의 주솟값을 얻어 포인터 변수를 만드는 것이 가능합니다. 주의할 점은 객체 인스턴스가 없다면 "static" 메서드 혹은 "static" 데이터 멤버만 포인터로 접근 가능하다는 것입니다.
2. 타입 에일리어싱 활용
classA myClass = classA(123);
// 타입 에일리어싱을 활용한 클래스 메서드 포인터 초기화
using MthdPtr = double (classA::*) () const;
MthPtr myMthdPtr = &classA::getValue;
// auto를 활용한 클래스 메서드 포인터 초기화
auto myMthdPtr2 = &classA::getValue;
// 클래스 메서드 포인터의 호출
cout << (myClass.*mthPtr)() << endl;
기존의 함수 포인터와 더불어 클래스 메서드 포인터 또한 타입 에일리어싱을 활용하여 초기화할 수 있습니다.
더불어, "auto" 키워드를 통해 더욱 간단한 방법도 존재합니다!
'언어 > Basic C++' 카테고리의 다른 글
[Basic C++] #60_스마트 포인터 (0) | 2022.09.28 |
---|---|
[Basic C++] #59_가비지 컬렉션 (1) | 2022.09.27 |
[Basic C++] #57_동적 메모리 (1) | 2022.09.20 |
[Basic C++] #56_cctype, 대문자+소문자 확인 (0) | 2022.09.15 |
[Basic C++] #55-7_템플릿 변수 (0) | 2022.08.10 |