포인터에 대해 설명해보세요.
포인터(pointer)
포인터(pointer)는 프로그래밍 언어에서 다른 변수, 혹은 그 변수의 메모리 공간주소를 가리키는 변수를 말한다. 포인터가 가리키는 값을 가져오는 것을 역참조(dereferencing)라고 한다.
포인터는 어셈블리어, C, C++, 파스칼 등 하위 레벨까지 제어할 수 있는 언어에서 주로 많이 쓰이며, 모듈라-2, 에이다와 같은 언어에서는 극히 제한적으로 사용되고, 자바, 에펠 등에서는 완전히 숨겨져 사용할 수 없다.
첫 번째 부류의 언어에서는 포인터를 메모리의 임의의 주소를 가리키도록 할 수 있으며 포인터의 연산도 가능하다. C#의 경우 제한적으로 포인터가 사용 가능하다. 일반적으로 포인터는 메모리 주소로 바꿀 수 있다. 포인터는 다른 변수나 함수를 가리키도록 사용된다.
C언어의 포인터
모든 변수는 메모리에 값을 저장한다. const와 같은 고정 값 변수 외의 모든 변수는 메모리 중에 RAM에 할당된다. 이러한 메모리의 공간을 구별하는 것이 메모리 주소 값이다. 주소로 각각의 위치를 구별 한다. 포인터 변수 모두는 메모리의 주소를 지정하는 값을 가진다.
데이터가 존재하는 주소 값을 사용하여 액세스 한다. 즉, 어떤 번지의 메모리에 값을 쓰거나 또는 읽어 오는 방식이다. 정적변수 역시 메모리에 배치되고 결국은 주소 값을 가질 것이다. 그러나 차이점은 기계어 코드에 주소 값을 고정하여 액세스 된다. 그러나 포인터 변수는 주소 값을 가지고 액세스하기 때문에 임의의 위치를 바꿀 수도 있게 된다.
전역변수의 정적변수는 기계어 코드에 주소 값을 고정하는 방식이 일반적이다. 지역변수는 스택 또는 CPU의 레지스터를 써서 위치 값을 설정 한다. 포인터 변수는 메모리에 주소 값을 저장하는 방식이기 때문에 이 주소 값을 읽어 실제 데이터를 액세스 한다. 메모리 액세스 모드 중에 직접주소방식(direct access mode)으로 데이터를 액세스 한다.
메모리의 주소는 CPU을 설계한 설계 기준에 따라 주소 값의 길이와 방식이 결정된다. 일반적인 용도의 대부분의 CPU는 메모리를 지정하는 길이(비트 수)는 동일하다. RAM이든 ROM/FLASH 이든 모든 주소는 같다. MCU(8051,...)은 오히려 많은 경우 메모리 영역을 나누어 다른 주소체계를 사용 한다.
8051은 내부의 256바이트 내에 변수를 할당 한다. 256바이트는 적기 때문에 많은 데이터를 처리하기 위해 변수는 잡을 수 없다. 많은 양의 데이터를 저장하기 위해 16비트의 저장 공간을 갖는 주소체계를 같이 사용한다. 그리고 양쪽의 액세스는 기계어 코드를 분리해서 액세스 한다. 이럴 경우는 주소 값이 8비트 또는 16비트가 필요하다. C언어 컴파일러에서 이를 지정할 수 있는 방법을 제시한다.
포인터 변수의 유연성은 프로그램 작성의 유연성과 연관된다. C언어가 UNIX 계열의 OS 작성 할 때 사용하였으므로 커널의 프로그램 소스를 보면 상당히 많은 부분 포인터 변수를 볼 수 있다. 유연성은 경우에 따라서 단점으로도 작용할 수 있다. 포인터 값에 따라 정의 되지 않는 메모리 영역을 액세스 할 수 있기 때문이다. 물론 정적 변수도 스스로의 배열 등의 공간 밖을 액세스 할 수 있지만, 포인터를 사용하면 이것이 좀 더 복잡해진다.
[포인터 예제]
커뮤니티 Q&A
위 이론과 관련된 게시글이에요.
이해가 안 되거나 궁금한 점이 있다면 커뮤니티에 질문해 보세요!
게시글 작성하기