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に設定します。