포인터 사용하기

이재홍 http://www.pyrasis.com 2014.12.17 ~ 2015.02.07

Go 언어는 C, C++와 마찬가지로 메모리 주소를 표현하는 포인터를 지원합니다. 먼저 var 키워드로 포인터형 변수를 선언해보겠습니다.

  • var 변수명 *자료형
var numPtr *int // 포인터형 변수를 선언하면 nil로 초기화됨

fmt.Println(numPtr) // nil

C 언어와는 달리 * (Asterisk, 애스터리스크)를 자료형 앞에 붙입니다. 그리고 포인터형 변수를 선언하면 nil로 초기화됩니다.

nil
Go 언어는 NULL 값을 nil로 사용합니다. 단, C 언어에서 NULL이 정수 0으로 정의되어 있지만 Go 언어에서 nil은 숫자 0이 아닙니다.

fmt.Println(nil == 0) // 컴파일 에러

빈 포인터형 변수는 바로 사용할 수 없으므로 new 함수로 메모리를 할당해야 합니다.

  • 포인터_변수 = new(자료형)
var numPtr *int = new(int)

fmt.Println(numPtr) // 0xc0820062d0: 메모리 주소. 시스템 마다, 실행할 때마다 달라짐

실행 결과

0xc0820062d0

new 함수는 지정한 자료형의 크기에 맞는 메모리 공간을 할당합니다. Go 언어는 메모리를 관리해주는 가비지 컬렉션을 지원하므로 메모리를 할당한 뒤 해제하지 않아도 됩니다.

포인터형 변수에 값을 대입하거나, 가져오려면 역참조(dereference)를 사용합니다.

  • *포인터_변수명
var numPtr *int = new(int) // new 함수로 공간 할당

*numPtr = 1          // 역참조로 포인터형 변수에 값을 대입

fmt.Println(*numPtr) // 1: 포인터형 변수에서 값을 가져오기

실행 결과

1

변수를 선언할 때 *를 붙이면 포인터형 변수가 되지만, 변수를 사용할 때 *를 붙이면 역참조가 됩니다. 여기서 포인터형 변수에는 메모리 주소만 저장됩니다. 따라서 포인터형 변수에 값을 바로 대입하지 않고, 역참조를 사용하여 메모리 주소에 값을 대입하거나 가져옵니다.

*numPtr = 1numPtr에 저장된 메모리 주소로 접근하여 값을 대입합니다. 그리고 *numPtrnumPtr에 저장된 메모리 주소에 접근하여 값을 가져옵니다.

일반 변수에 참조(레퍼런스)를 사용하면 포인터형 변수에 대입할 수 있습니다.

  • &변수명
var num int = 1
var numPtr *int = &num // 참조로 num 변수의 메모리 주소를 구하여 
                       // numPtr 포인터 변수에 대입

fmt.Println(numPtr) // 0xc0820062d0: numPtr 포인터 변수에 저장된 메모리 주소
fmt.Println(&num)   // 0xc0820062d0: 참조로 num 변수의 메모리 주소를 구함
0xc0820062d0
0xc0820062d0

변수 앞에 &를 붙이면 해당 변수의 메모리 주소를 뜻합니다. 따라서 포인터형 변수에 대입할 수 있습니다.

Go 언어에서는 메모리 주소를 직접 대입하거나 포인터 연산을 허용하지 않습니다. 따라서 다음과 같이 메모리 주소를 직접 조작할 수는 없습니다.

var numPtr *int = new(int)

numPtr++              // 컴파일 에러. 포인터 연산은 허용하지 않음
numPtr = 0xc0820062d0 // 컴파일 에러. 메모리 주소를 직접 대입할 수 없음

fmt.Println(numPtr)

저작권 안내

이 웹사이트에 게시된 모든 글의 무단 복제 및 도용을 금지합니다.
  • 블로그, 게시판 등에 퍼가는 것을 금지합니다.
  • 비공개 포스트에 퍼가는 것을 금지합니다.
  • 글 내용, 그림을 발췌 및 요약하는 것을 금지합니다.
  • 링크 및 SNS 공유는 허용합니다.

Published

01 June 2015