C ++ポインタ(動的メモリの受け渡し)を理解できるようにする例

私はC / C ++ポインターをよく理解していませんが、ポインターはC言語の特徴であり、その本質です。ポインターはデータオブジェクトのメモリアドレスです。定数ポインター、配列ポインター、関数ポインター、このポインター、ポインター転送、ポインターへのポインターなどを含むポインターの問題はすべて、主要企業の永続的なテストポイントです。ポインタを理解して理解するための例を見てみましょう

#include <iostream>
using namespace std;

void swap1(int p,int q){

    int temp;
    temp = p;
    p = q ;
    q = temp;
}

void swap2(int *p,int*q){
   int *temp;
   *temp = *p;
   *p = * q;
   *q = *temp;
}

void swap3(int *p,int *q){
  int *temp;
  temp = p ;
  p = q;
  q = temp;
}
void swap4(int *p,int *q){
  int temp;
  temp = *p;
  *p = *q;
  *q = temp;

}
void swap5(int &p,int &q){
 int temp;
 temp = p;
 p = q;
 q = temp;

}
int main(){
 int a,b;
 swap1(a,b);
 //swap2(&a,&b);
 //swap3(&a,&b);
 //swap4(&a,&b);
 //swap5(a,b);
cout<<a<<" "<<"b"<<endl;
return 0;
}

この例には、関数パラメーターの受け渡し、値の受け渡し、ポインターの受け渡し(アドレスの受け渡し)、および参照の受け渡しに関する知識ポイントが含まれています。

swap1(a、b)、swap2(a、b)、swap3(a、b)、swap4(a、b)、swap5(a、b)をそれぞれ実行します。

彼らはどのように異なる結果をもたらすでしょうか


1. sawp1(a、b)の場合、pとqは正式なパラメーター、aとbは実際のパラメーター、swap1はコピーする価値がありますが、正式なパラメーターp、q、p、qの値は関数本体で変更されます。の値は実際に交換されますが、これらはローカル変数にすぎず、メイン関数のaとbには影響しません。関数のライフサイクルが終了すると、pとqが配置されているスタックも削除されます。


2.swap2(&a、&b)は関数パラメーターの本体のアドレスに渡され、* p * qはメモリーアドレスポインターの実際のパラメーターa、bを指します。

だが!!!

注意を払う!


int *temp;
*temp = *p;

このコードの意味は次のとおりです。新しいポインタ* temp;を作成しましたが、彼にメモリを割り当てなかったため、

* temp = * pは割り当てであり、ポインタではありません。ポインタpが指すメモリ内の値を、ポインタtempが指すメモリ内の値に割り当てるという理解に注意してください。しかし、* tempに割り当てられたメモリはありませんか?したがって、システム割り当て時に一時に* tempにランダムなアドレスを与え、値を格納させます。割り当てられたランダムアドレスは「事故」であり、機能終了後は復旧しません!これにより、メモリリークが発生します。以下に示すように


では、このコードはデータ交換を実現できますか?実際、それはコンパイラーに依存します。vs2008のようなより厳密なコンパイラーはエラーを報告します。

3. swap3(a、b)は、swap2とは異なる過去のアドレスを渡します

*temp = *  p ;//swap2 赋值
temp = p; //swap3 指向
/*swap2和swap3同样都没给temp指针分配内存
 *不同的是以上这两段代码。temp=p是指向,而不是复制了,temp是指向了p指针所指向的地址,也就是a
 */

そしてコード
p = q;
q = temp;
/*其意思就是指针p指向了指针q所指向的地址,q又指向了指针temp所指向的地址,其实和temp=p是一个意思;
如下图所示
*/


したがって、swap3はポインタのポイントのみを変更し、aとbの値は変更しませんでした。

非常に鮮やかな例を挙げてください。2つのウェアハウスaとbがあり、pとqがそれぞれスペアキーであるとします(スペアキーであることに注意してください)。次に、キーpとqの機能を変更する関数body swap3()を入力し、pを使用してbを開きます。倉庫qは倉庫aを開くために使用されますが、倉庫a自体の商品に変更はありません。そこに保管されている米はまだ米であり、倉庫bには元々唐辛子である唐辛子が含まれていました。関数の終了時に、2つの予備の「キー」が自動的に破棄され、メインキーを使用してメイン関数のウェアハウスaとbが開かれ、値は変更されません。

4. swap4、ポインタが指すアドレスの値を変更します

int *temp;
temp = *p;
*p = q;
*q = temp;
ポインタpが指すアドレスの値を一時ポインタが指すアドレス* p = qに割り当てます。つまり、qポインタが指すアドレスは、ポインタpが指すアドレスの値に割り当てられるため、ポインタpは( address)の値はbになります(bはqポインターが指すアドレスです)。同様に、ポインターtempが指すアドレスは、qポインターが指すアドレスの値に割り当てられます。これは、最初のpポインターを意味します。指しているアドレスの値は、qポインターが指しているアドレスの値に割り当てられます。実際、交換の本質はこれです。pの初期値をqの値に置き換える必要があり、qの値を初期pの値に置き換える必要があるため、pの初期値のみが一時的に保存されます。

5.swap5とswap4は似ています。これは参照パスであり、変更の結果は実際のパラメーターに直接影響します。

void swap5(int &p,int &q){
int temp = p;
p = q;
q = temp;
}
いわゆる参照転送とは、関数が呼び出されると、実際のパラメーターのアドレスが関数に渡され、関数内のパラメーターの変更が実際のパラメーターに影響を与えることを意味します。変数参照を関数に渡すので、この関数は、そのパラメーター(変数)の値を変更できます。引数とパラメーター は同じアドレスを 参照 するため、パラメーターの値を変更すると、引数の値も変更されます。

 
  
 

おすすめ

転載: blog.csdn.net/sinat_35803474/article/details/76686061