「アドレス」は変数が配置された場所を示す
var n int = 100
fmt.Println(n) // 100
fmt.Println(&n) // 0xc0000167b0
&
はアンパサンドといい、変数がメモリ上のどこのアドレスに格納されているかを知るために利用します
コンピュータは変数を以下のようなイメージで保存します。
メモリの各領域にアドレス(16進数)が割り振られています。
なので、アドレスと値は紐づいている状態ですね。
アンパサンド&
を用いることで、「その変数がメモリ上のどこにあるのか」を知ることができるのです。
ポインタはアドレスを格納するためのオブジェクトである
var n int = 100
var p *int = &n
fmt.Println(p) //0xc00007c770
C言語のポインタ構文のつまづきどころ
を参照すると、孫引きとなってしまいますが、このような記述がなされていました。
ポインタ (pointer)とは、あるオブジェクトがなんらかの論理的位置情報でアクセスできるとき、それを参照するものである。有名な例としてはC/C++でのメモリアドレスを表すポインタが挙げられる。(ja.wikipedia.org)
In computer science, a pointer is a programming language object, whose value refers to (or "points to") another value stored elsewhere in the computer memory using its address.(en.wikipedia.org)
なので、「ポインタ = アドレス」と捉えても、差し支えはないです。(厳密には違いますが....)
上記のコードのvar p *int = &n
の部分で、変数pはintのポインタ型を宣言して、変数nのアドレスを格納しています。
この時点でp
は「ポインタ」と呼ぶことが可能です。
*int
はint用のアドレスを格納する「ポインタ型」です。
&
と*
を利用すれば何となくわかる
var n int = 100
fmt.Println(n) // 100
fmt.Println(&n) // 0xc0000167b0
fmt.Println(*&n) // 100
fmt.Println(&*&n) // 0xc0000167b0
ややこしいのですが、*
を型の前ではなく、変数の前に置くと「アドレスの実体」を参照することができます。