2018년 5월 1일 화요일

C++ 関数へ値渡し、ポインタ渡し、参照渡し

C++で関数呼び出しの際は引数を値(基本形)、ポインタ(タイプ)、参照(タイプ)で渡します。
ポインタと参照の使用区分をよく理解してなかったので整理します。

C++ 値渡し、ポインタ渡し、参照渡しを使い分けよう



1.値渡し
基本形(int,float,bool,char..)の渡しに主に使用
値渡し=コピー になりコピーされた引数を変更しても元の変数の値は変わらない。
コピーでの負荷があるので、サイズが大きいデータ形には一般的に使わない。

--------------------
#include <iostream> 
using namespace std; 
void printFunc(int a) 

     cout << "funcAddress. " << &a << endl;
     cout << "func1. " << a << endl; 
     a+=a; 
     cout << "func2. "<< a << endl; 

int main(void) 

     int i=2; 
     cout << "mainAddress. " << &i << endl;
     cout << "main1. " << i << endl; 
     printFunc(i); 
     cout << "main2. "  << i << endl; 
     return 0; 
}

mainAddress. 0x6ffe3c  <- 元の変数のメモリアドレス
main1. 2 
funcAddress. 0x6ffe10   <- コピーされたの引数のメモリアドレス
func1. 2 
func2. 4       <- 関数にコピーされた引数は更新されるが
main2. 2      <- 元の変数の値は変わらない

--------------------

2.ポインタ渡し
変数のメモリアドレスを渡す。
間接参照の形で元の変数を変更可能
注意:NULLポインタが可能ので使用前にNULLチェックが必要

--------------------
#include <iostream> 
using namespace std; 
bool printFunc(int* a) 

     if(a==nullptr)   <-NULLポインタチェックがないとエラーになる。
     { 
          cout << "NullPtr Error" << endl; 
          return true; 
     }
     cout << "funcAddress. " << a << endl; 
     cout << "func1. " << *a << endl; 
     *a+=*a; 
     cout << "func2. "<< *a << endl; 
     return false;

int main(void) 

     printFunc(nullptr); 
     int i=2; 
     cout << "mainAddress. " << &i << endl; 
     cout << "main1. " << i << endl; 
     printFunc(&i); 
     cout << "main2. "  << i << endl; 
     return 0; 
}

NullPtr Error       <- NULLポインタがチェックされます。
mainAddress. 0x6ffe3c  <- 元の変数のメモリアドレス
main1. 2 
funcAddress. 0x6ffe3c   <- ポインタ変数のメモリアドレス
func1. 2 
func2. 4            <- 関数のポインタ変数を変更すると
main2. 4              <- 同じメモリアドレスの元の変数も変わります。
--------------------

2.参照渡し
参照形はC++で追加された安全な、制限的なポインタ
元の変数の別称
NULL参照は不可で必ず初期化が必要
ポインタ渡し、参照渡しはオーバーロード可能

--------------------
#include <iostream> 
using namespace std; 
bool printFunc(int* a) 

     cout << "Pointer" << endl; 
     if(a==nullptr) 
     { 
          cout << "NullPtr Error" << endl; 
          return true; 
     } 
     cout << "funcAddress. " << a << endl; 
     cout << "func1. " << *a << endl; 
     *a+=*a; 
     cout << "func2. "<< *a << endl; 
     return false; 

bool printFunc(int& a) 

     cout << "Reference" << endl; 
     cout << "funcAddress. " << &a << endl; 
     cout << "func1. " << a << endl; 
     a+=a; 
     cout << "func2. "<< a << endl; 
     return false; 


int main(void) 

     printFunc(nullptr); 
     int i=2; 
     cout << "mainAddress. " << &i << endl; 
     cout << "main1. " << i << endl; 
     printFunc(&i); 
     printFunc(i); 
     cout << "main2. "  << i << endl; 
     return 0; 
}

Pointer 
NullPtr Error 
mainAddress. 0x6ffe3c 
main1. 2 
Pointer 
funcAddress. 0x6ffe3c 
func1. 2 
func2. 4 
Reference 
funcAddress. 0x6ffe3c 
func1. 4 
func2. 8 
main2. 8

--------------------

関数に引数を渡すとき、変数の維持が必要場合は安全のためにconstを積極活用しましょう!

C++ 함수에 값전달, 포인터전달, 참조전달

댓글 없음:

댓글 쓰기

1、2、QWER! in OSAKA (大阪 2025/4/10(木) Yogibo META VALLEY)

https://www.creativeman.co.jp/event/qwer-osaka/ QWER - CREATIVEMAN PRODUCTIONS 主催:LIVET 企画:ソニー・ミュージックソリューションズ 招聘:クリエイティブマンプロダクション 制作協力:クリエイテ...