이번엔 맨날 헷갈리는 포인터 상수, 상수 포인터에 대해 공부한다.

번역에 따라 논란이 있어 한국 용어는 잘 사용하지 않는다고 한다.

대신 const int, int const와 같이 사용법을 통해 무엇인지 알아두자.

const

  • 상수를 선언하는 키워드

  • const로 선언된 변수, 포인터, 멤버함수, 객체를 상수화 시킨다.


빌트인 타입 const

  • int와 같은 빌트인 타입 변수를 상수화할 때, const의 위치는 타입 앞뒤 무관하며, 둘 다 같은 의미이다.
#include <iostream>
using namespace std;

int main()
{
	int num = 10;
	
	const int constNum = num;
	int const constNum = num;	// 둘 다 똑같다.
}


포인터 상수 (constant pointer)

int* const ptr
  • 값을 변경할 수 있으나, 주소 변경은 불가능
#include <iostream>
using namespace std;

int main()
{
	int num = 1;
	int* const ptr = &num;

	*ptr = 4;	// 간접접근을 통한 값의 변경이 가능하다.
	cout << "ptr: " << *ptr << '\n';

	int num2 = 100;
	// ptr = &num2;	// 에러: 가리키는 주소의 변경은 불가능하다.

	return 0;
}
ptr: 4
  • 배열명은 포인터 상수

  • 배열명 = 시작주소값이며, 배열의 요소들은 주소들이 연속적으로 붙어있다.

    이 때 연속적인 주소 정보를 변경시키면 안 되기 때문에, 주소를 바꾸지 못하게 주소가 상수값으로 고정되어 있다.

  • 그러므로 배열명은 포인터 상수이며, 배열의 주소를 변경할 수 없다.

#include <iostream>
using namespace std;

int main()
{
	int nums[] = { 1, 2, 3 };
	
	*nums = 5;	// 값 변경 가능

	cout << "배열의 첫번째 값 : " << *nums << '\n';
	cout << "배열의 값 : ";
	for (int i = 0; i < 3; i++)
	{
		cout << nums[i] << ' ';
	}

	int a = 10;
	int* ptr = nums;	// 새로운 포인터 변수가 배열 nums의 첫 번째 값을 가리킴
	ptr = &a;		// 가능
	// nums = &a;		// 불가능

	return 0;
}
배열의 첫번째  : 5
배열의  : 5 2 3


상수 포인터 (pointer to constant)

const int* ptr
  • 값을 변경할 수 없지만, 주소 변경은 가능

  • 포인터를 이용해 변수의 값을 변경하는 것을 막는다.

  • 가리키는 원본 변수 자체가 상수화되진 않는다.

#include <iostream>
using namespace std;

int main()
{
	int num = 1;
	int* ptr1 = &num;
	const int* ptr2 = &num;

	*ptr1 = 2;
	num = 3;
	// *ptr2 = 4;	// 에러: 간접접근을 통한 값의 변경은 불가능하다.
	cout << "주소값 변경 전" << '\n';
	cout << "ptr1: " << ptr1 << '\n';

	int num2 = 100;
	ptr1 = &num2;	// 가리키는 주소의 변경은 가능하다.
	cout << "주소값 변경 후" << '\n';
	cout << "ptr1: " << ptr1;

	return 0;
}
주소값 변경 
ptr1: 000000A3EED3FC94
주소값 변경 
ptr1: 000000A3EED3FCF4


상수 포인터 상수 (constant pointer to constant)

const int* const ptr = array;
  • 값의 변경 불가능, 주소의 변경 불가능
#include <iostream>
using namespace std;

int main()
{
	int num = 1;
	int num2 = 2;
	const int* const ptr = &num;
	// *ptr = 2;		// 값 변경 불가능
	// ptr = &num2;		// 주소 변경 불가능
	return 0;
}


결론

  • int* const == 포인터 상수 == constant pointer == 값 변경 가능, 주소 변경 불가능

  • const int* == 상수 포인터 == pointer to constant == 값 변경 불가능, 주소 변경 가능

  • 배열명은 포인터 상수

  • 참고) 한국 용어 보면 더 헷갈림


참고링크

https://en.cppreference.com/w/cpp/language/pointer

태그:

카테고리:

업데이트:

댓글남기기