[C] 포인터

Posted by 신희준 on September 23, 2018


2018 - 09 - 23 (일)


  • 참고 문헌 : C언어의 정석 [남궁성 지음]

포인터

  • 1.1 메모리 주소

메모리 = 컴퓨터에 장착된 램 (RAM) 의미

메모리는 물리적으로 여러개의 칩으로 구성되어 있지만, 운영체제는 메모리를 하나의 연속된 저장 공간으로 간주한다. 이 메모리는 1바이트 단위로 나누어 저장되며 0부터 시작하여 1씩 증가하는 일련번호가 붙는데 이것이 메모리 주소이다.

int i = 1 ; 

위의 문장이 수행되면 메모리에 int 타입의 값 (4Byte) 를 위한 저장 공간이 마련되고, 그 저장 공간에 1이 저장된다. 예를 들어 메모리 저장 주소가 0x100 부터 시작하여 0x103 까지 4개 단위의 메모리에 저장될 경우 int의 메모리 공간이 4 byte 이므로 메모리 시작 주소를 알면 저장 범위를 쉽게 알 수 있다.

  • 1.2 포인터 란?

포인터는 어떤 대상을 가리키는 것으로 메모리에 저장된 것, 예를 들어 변수나 배열을 가리키기 위한 것이다. 가리킨다는 것은 포인터가 어떤 대상의 주소를 저장하고 있다는 것을 의미한다.

포인터는 메모리 주소를 저장하기 위한 변수이다.

선언하는 방법, 값을 저장하고 읽어오는 방법 모두 변수와 같다. 포인터는 단지 그 메모리의 주소를 저장하기 위한 것일 뿐.

변수와 마찬가지로 const 키워드를 붙여서 상수로 만들 수 있으며 이를 포인터 상수 라고 한다.

  • 1.3 포인터의 선언

포인터의 선언방법은 변수의 선언방법과 동일하다. 다만 포인터가 가리키는 대상의 타입에 ‘*’ 을 붙인다.

예를 들어 int 타입의 변수를 가리키기 위한 포인터는 아래와 같이 선언한다.

int * ptr;

1) 위의 경우 ptr 의 타입이 ‘int’가 아니라는 것에 주의해야된다. ptr이 가리키는 대상의 타입이 ‘int’이고 ptr의 타입은 ‘int*’ 이다.

//포인터 선언시 주의점
int* ptr1;  //포인터는 타입 옆에 붙이도록 하자
int *ptr1;  //변수 이름 옆에 * 기호를 붙이면 의도한 바와 다른 결과를 가질 수 있다. 

1.4 포인터에 주소 저장하기 -& 연산자

포인터에 주소를 저장하려면 먼저 포인터가 가리킬 대상의 주소를 얻어야 한다. 그 일을 하는 것이 ‘&’ 연산자이다. ‘&’ 연산자는 피연산자의 주소를 반환하며, 피연산자로 변수나 배열요소처럼 저장공간을 가지고 있는 것만 허용한다.

int i = 1;
int* ptr = &i; // 변수 i의 주소를 포인터 ptr에 저장
int main(void)
{
	int i = 5;
	int* p = &i;
	printf("변수 i에 저장된 값을 출력 : i = %d\n" , i);
	printf("변수 i의 주소를 출력 : &i=%p\n" , &i);
	printf("포인터 p에 저장된 값(주소) 출력 : p = %p\n" , p);
	printf("포인터 p의 주소를 출력 :  &p = %p\n" , &p);
    
}

/* 결과

변수 i에 저장된 값을 출력 : i = 5
변수 i의 주소를 출력 : &i=0061FF2C
포인터 p에 저장된 값(주소) 출력 : p = 0061FF2C
포인터 p의 주소를 출력 :  &p = 0061FF28
*/

1.5 포인터로 값 읽어 오기

포인터가 가리키는 대상에 저장된 값을 가져올 때는 ‘’ 연산자를 사용한다. ‘’ 연산자는 간접 참조 연산자라고 하는데 ‘*피연산자’의 형태로 사용되는 단항 연산자로 포인터가 가리키는 주소에 저장된 값을 읽어서 반환

// 위의 메인문에서 
printf("포인터 값 불러오기 : %d :" , *p);

//결과 : 5