Goの勉強をしていたら再発見(というより復習)しまして、基本が抜け落ちているなぁと痛感…。
C言語を勉強した時に学んだ気がするんですが、完全に頭から抜けていたので書いておきます。
この記事では例としてC,Goで例示します。
値渡し
まずは普通に変数の値を関数に渡してみます。
# include<stdio.h>
int plus1(int x){
x = x + 1 ;
return x ;
}
int main(void){
int a ;
a = 1 ;
plus1(a);
printf("a = %d\n",a);//a = 1と表示される
return 0;
}
package main
import "fmt"
func plus1(x int) int{
x = x + 1
return x
}
func main(){
a := 1
a1 := plus1(a)
fmt.Println("a =", a) //a = 1と表示される
fmt.Println("a + 1 =", a1) //a + 1 = 2と表示される
}
ポインタ渡し
次にポインタを渡してみます。
# include<stdio.h>
int plus1(int *x){
*x = *x + 1 ;
return *x ;
}
int main(void){
int a ;
a = 1 ;
plus1(&a);
printf("a = %d\n",a);//a = 2と表示される
return 0;
}
package main
import "fmt"
func plus1(x *int) int{
*x = *x + 1
return *x
}
func main(){
a := 1
a1 := plus1(&a)
fmt.Println("a =", a) //a = 2と表示される
fmt.Println("a + 1 =", a1) //a + 1 = 2と表示される
}
結果が変わりました。
まとめ
変数a
を普通に渡すと、関数にはa
をコピーしたものが渡されます。なので、元々のa
には変更が適応されません。
ポインタを渡した場合は、a
が格納されているアドレスを直接修正しているので、「aに1を足す」という処理から「aが指しているアドレスの中の数値に1を足す」という処理に変わっています。
なので最終的に同じ場所を見ている変数a
の値も1から2になります。
※ポインタを渡した場合もメモリアドレスのコピーを渡しているだけのようです。コメントにてshiracamusさんよりご指摘いただきましたので、詳しくはコメント欄を参照してください。(とても解りやすく解説して頂いてます。)
最後に
できる人からしたら当たり前のことですが、今まで曖昧にしたままだったのでこの機会に復習しました。少しでも誰かのお役に立てばと思います。