C++における関数へ変数を渡すときの話

こんにちは、ぷないしんです。

 

関数への値を渡す方法の話をしたいと思います。

 

関数へ値を渡すときの記述方法ですが下記の三つがあるみたいです。

 

①普通の渡し方(値渡しと言われる)

②ポインタ渡し

③参照渡し

 

普通の渡し方とポインタ渡しはCにもありますが、参照渡しについてはC++特有の渡し方です。

 

という事で上記の三つを詳しく見ていきましょう。

 

①普通の渡し方

まずコードを記述してみます。

#include <iostream>

using namespace std;

void kansu(int a){
    a = a + 1;
    cout << a << "\n";
}

int main(){
    int x = 1 ;
    cout << x << "\n";
    kansu( x );
    cout << x << "\n";
}

これで実行結果は

f:id:punainen:20210315132556p:plain

関数1

こうなりました。

渡された数値を+1し、その値を出力するだけの関数を作成しました。

 

ここで注目してほしいのはxの値は関数では+1されずに1のままという事です。

 

これは何を意味しているかというと

xの値を直接処理しているのではなくコピーしたものを処理しているという事です。

なのでコピーされた引数の値をいくら変更しようが、関数を呼び出した側の変数の処理は行われません。

 

調べてみたところ、わざわざコピーを作成しているので、引数が大きな値であれば処理に時間がかかるので、そのような可能性があるときにはこの渡し方は推奨されないとのことです。

 

次に②のポインタ渡し

例によってコードの記述から行います

#include <iostream>

using namespace std;

void kansu(int* a){
    *a = *a + 1;
    cout << *a << "\n";
}

int main(){
    int x = 1 ;
    cout << x << "\n";
    kansu( &x );
    cout << x << "\n";
}

①との差異は

・関数の定義時にint*

・関数の中身の変数それぞれにa*

・メイン関数で関数呼び出し時、変数に&x

 

そして結果の方は

 

f:id:punainen:20210315134319p:plain

関数2

こうなりました。

 

本来はnullチェックというものを行わないといけないようなのですが、それはまた別の機会にお話しするとして結果の方に注目してみましょう。

 

関数を呼び出した後にxの値が書き変わっているではありませんか、これはつまり

関数の呼び出し元の変数を書き換えることができるということですね。

 

ポインタなのでメモリ上のアドレスを渡しているという言い方になります。

渡してもらったアドレスを関節的に参照することによってこのような処理になっています。

 

 

そして③参照渡しですがこれはCには存在せず、C++に独自に実装されている渡し方で、下記の様に記述します。

#include <iostream>

using namespace std;

void kansu(int& a){
    a = a + 1;
    cout << a << "\n";
}

int main(){
    int x = 1 ;
    cout << x << "\n";
    kansu( x );
    cout << x << "\n";
}

 

結果の方は

f:id:punainen:20210315134319p:plain

②のポインタ渡しと同じ結果ですね。

 

この渡し方で注目してほしいのは、記述の方法です。

 

なんと関数を定義するときにint&とするだけで、ポインタ渡しと同じ結果になったではありませんか。

 

どういう渡し方なのかという元の変数に別の名前を付ける渡し方と言われています。

 

どういうことかというと

 

変数Nipponに対して参照渡しで(int& Japan)で渡すと変数Nipponも変数Japanも同じメモリアドレスを指す事になります。

 

なので呼び出し元の変数にアクセスし、書き換えることが出来るという訳です。

 

つまり、参照渡しは変数を関数で受け渡す時にポインタ渡しの記述を簡易的に行えてしまうという事でとりあえず理解してけばいいかもしれないですね。

参照渡しをするとポインタ渡しの独特な記述がいらないので、我々のような初心者には扱いやすくなります。

 

 

 

どの渡し方も使い方が違いますので一概にこの渡し方をしておけば問題ない!ということはないので状況によってちゃんと使い分けるようにしていきたいです。

 

それぞれの詳しい話はまた後日にします。

 

それではお疲れ様でした。

 

ぷないしん