go-pointer

kyunhyun94·2021년 12월 30일

👩🏻‍🎓Pointer

  • Go 언어는 C, C++와 마찬가지로 메모리 주소를 표현하는 포인터를 지원한다
var numPtr *int // 포인터형 변수를 선언하면 nil로 초기화됨

fmt.Println(numPtr) // nil
  • C 언어와는 달리 * (Asterisk, 애스터리스크)를 자료형 앞에 붙인다. 그리고 포인터형 변수를 선언하면 nil로 초기화된다
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 = 1은 numPtr에 저장된 메모리 주소로 접근하여 값을 대입, 그리고 numPtr은 numPtr에 저장된 메모리 주소에 접근하여 값을 가져온다

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

&변수명

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)

💯함수에서 포인터형 매개변수 사용하기

func hello(n int) {
	n = 2 // 매개변수 n에 2를 대입
}

func main() {
	var n int = 1

	hello(n) // 1이 들어있는 변수 n을 hello 함수에 넘김

	fmt.Println(n) // 1: hello 함수안의 n에 2를 대입했지만 바깥의 n은 영향이 없음
}

실행결과

1
func hello(n *int) {
	*n = 2 // 포인터 변수 n를 역참조하여 메모리에 2를 대입
}

func main() {
	var n int = 1

	hello(&n) // 1이 들어있는 변수 n의 메모리 주소를 hello 함수에 넘김

	fmt.Println(n) // 2: hello 함수에서 n의 메모리 공간에 2를 대입했으므로 바깥에 있는 n의 값이 바뀌었음
}

실행결과

2

hello 함수에서 포인터형 매개변수를 받은 뒤 *를 사용하여 값을 2로 변경. 이렇게 하면 함수 바깥의 n의 값도 2가 된다. 즉, 메모리 주소를 넘겨주었으므로 기존 변수의 값이 바뀌게 된다

profile
일하기싫어

0개의 댓글