Go(golang) 포인터(pointer * &)

 안녕하세요. 이번에는 go언어에서 포인터에 대해서 이야기 하도록 하겠습니다.



사진1) int64형 포인터가 int64변수의 주소를 저장

각 메모리마다 주소가 있는데 포인터 변수는 이 주소를 저장합니다. 포인터를 이용하여 해당 변수를 수정할수 있습니다.


package main

import (
"fmt"
)


func main(){

// int64변수 할당
var num int64 = 30
// pointer를 포인터 int64로 할당
var pointer *int64

// pointer에 num주소를 저장
pointer = &num

// pointer의 주소를 확인
fmt.Printf("pointer address : %p\n", pointer)
// pointer가 가르키는 주소의 실제값을 확인
fmt.Printf("pointer value : %v\n", *pointer)

// pointer를 이용하여 num값을 60으로 변경
*pointer = 60

// pointer를 이용하여 num값 변경 확인
fmt.Printf("pointer value(change) : %v\n", *pointer)

}

코드1) 포인터를 이용하여 int64변수 주소값 저장 및 수정



사진2) 코드1의 결과


기본적으로 포인터는 nil값입니다. 하지만 nil값이 아니면 다른 메모리 공간을 가르키고 있다는 뜻입니다.



package main

import (
"fmt"
)

func add5toInt(num int64) {
num += 5
fmt.Println("add5toInt result :", num)
}


func main(){
// int64변수 할당
var num int64 = 30

// add5toInt함수를 이용하여 num값의 5더하기
add5toInt(num)
fmt.Println("real result of num :", num)
}

코드2) num값을 함수로 변경


사진3) 코드2의 결과

코드2에서 'add5toInt'함수를 이용하여 num값을 변경할려고 했지만 변경하지 못했습니다. 그 이유는 함수에서 사용한 변수는 num값을 복사한 변수이기 때문입니다.


package main

import (
"fmt"
)

// 함수의 return값을 num(int64)으로 한다.
func add5toInt(num int64) int64{
num += 5
fmt.Println("add5toInt result :", num)
return num
}


func main(){
// int64변수 할당
var num int64 = 30

// add5toInt함수를 이용하여 num값의 5더하기
// add5toInt의 return값을 다시 num에 입력한다.
num = add5toInt(num)
fmt.Println("real result of num :", num)
}

코드3) num의 변경값이 반영되도록 코드 수정


사진4) 코드3의 결과

코드3에서는 'add5toInt'함수에 return값을 추가하여 main함수 안에 있는 num값에 입력합니다. 하지만 이는 추가적인 메모리(add5toInt함수에서의 num값 복사)가 필요합니다. 


package main

import (
"fmt"
)

// 함수에서 int64의 주소값을 받아서 처리한다.
func add5toInt(num *int64){
*num += 5
fmt.Println("add5toInt num address :", num)
fmt.Println("add5toInt result :", *num)
}


func main(){
// int64변수 할당
var num int64 = 30

// add5toInt함수를 이용하여 num값의 5더하기
// add5toInt num의 주소값을 입력한다.
add5toInt(&num)
fmt.Println("real result of num :", num)
}

코드4) pointer를 이용하여 num값을 함수에서 변경



사진5) 코드4의 결과값

코드4에서는 함수에 받는 인자를 num의 포인터로 하였습니다. 코드3과 달리 따로 return값이 필요가 없고 num에 바로 적용되는 것을 알수 있습니다.



package main

import (
"fmt"
)

type Student struct {
age int64
grade int8
gender string
name string
}


func main(){
// 학생 변수 설정
var stu1 Student = Student{
17,
3,
"male",
"alex",
}

// p_str1을 Student 포인터로 정의하고 stu1의 주소값을 입력한다.
var p_str1 *Student = &stu1
fmt.Println("initial value of stu1 :", stu1)
// p_str1이 저장하고 있는 주소값
fmt.Printf("%p\n",p_str1)
// stu1에 실제 위치한 주소값
fmt.Printf("%p\n",&stu1)
}

코드5) struct와 point를 이용한 코드



사진6) 코드5의 결과

위 코드에서 struct또한 포인터로 저장이 가능합니다. 



package main

import (
"fmt"
)

type Student struct {
age int64
grade int8
gender string
name string
}

func main(){
var p_str2 = &Student{}
var p_str3 = new(Student)
// fmt.Println(*p_str2, *p_str3)
fmt.Printf("p_str2 주소값(%p)과 초기값(%v)\n", p_str2, *p_str2)
fmt.Printf("p_str3 주소값(%p)과 초기값(%v)\n", p_str3, *p_str3)
}

코드6) 포인터 초기화 방법 2가지



사진7) 코드6의 결과


struct 포인터를 초기화 할시 코드6에 나온것처럼 2가지 방법이 있습니다. 포인터 변수 선언과 동시에 초기화 할것인지 아니면 new()내장함수를 이용하여 초기화 하는 방법입니다.




댓글

이 블로그의 인기 게시물

Lesson 12_1 프로퍼티 노드(Property Node)

DAQ로 전압 측정하기-2

Lesson 12_2 참조를 이용한 프로퍼티노드(Property Node)