1. 変数の宣言とメモリアドレスの表示
var ui1 uint16
fmt.Printf("memory address of ui1: %p\n", &ui1)
var ui2 uint16
fmt.Printf("memory address of ui2: %p\n", &ui2)
-
ui1
とui2
は、uint16
型の変数です。 -
&ui1
のように「&」を使うことで、変数のメモリアドレスを取得できます。%p
フォーマット指定子を使って、ポインタとして出力します。
2. ポインタの宣言と初期化
var p1 *uint16
fmt.Printf("value of p1: %v\n", p1)
p1 = &ui1
fmt.Printf("value of p1: %v\n", p1)
-
p1
はuint16
型のポインタです。初期状態ではnil
(何も指していない状態)です。 -
p1 = &ui1
によって、ui1
のメモリアドレスをp1
に代入します。これにより、p1
はui1
を指すようになります。
3. ポインタのサイズとメモリアドレス
fmt.Printf("size of p1: %d[bytes]\n", unsafe.Sizeof(p1))
fmt.Printf("memory address of p1: %p\n", &p1)
-
unsafe.Sizeof(p1)
は、ポインタのサイズをバイト単位で返します。通常、ポインタのサイズはシステムによって異なります(32ビットシステムでは4バイト、64ビットシステムでは8バイト)。 -
&p1
でp1
のメモリアドレスを出力します。
4. ポインタの間接参照
fmt.Printf("value of ui1(dereference): %v\n", *p1)
*p1 = 1
fmt.Printf("value of ui1: %v\n", ui1)
-
*p1
を使うことで、ポインタが指している変数(この場合はui1
)の値を取得します。この操作を「間接参照」と呼びます。 -
*p1 = 1
により、ui1
の値を1に設定します。この時点で、ui1
の値が変更されます。
5. 二重ポインタの使用
var pp1 **uint16 = &p1
fmt.Printf("value of pp1: %v\n", pp1)
fmt.Printf("memory address of pp1: %p\n", &pp1)
fmt.Printf("size of pp1: %d[bytes]\n", unsafe.Sizeof(pp1))
-
pp1
はp1
のポインタであり、二重ポインタです。これにより、ポインタのポインタを扱うことができます。 -
&p1
でp1
のアドレスをpp1
に代入します。
6. 二重ポインタを通じた間接参照
fmt.Printf("value of p1(dereference): %v\n", *pp1)
fmt.Printf("value of ui1(dereference): %v\n", **pp1)
**pp1 = 10
fmt.Printf("value of ui1: %v\n", ui1)
-
*pp1
はp1
を指し、**pp1
はui1
の値を直接参照します。 -
**pp1 = 10
により、ui1
の値を10に設定します。