C++ピットシリーズ(四)複合データ型の配列

17242 ワード

前言
配列は、同じデータ型のデータを複数格納できるデータ構造です.例えば、クラス全員の年齢を記憶したり、クラス全員の身長を記憶したりします.配列は簡単に見えるが,実際の応用では注意すべき点が多い.本文では、私が今直面している難点と重点をリストし、皆さんと分かち合いたいと思っています.漏れがあれば、読者の皆様に補足していただきたいと思います.
静的配列
定義#テイギ#
名前の通り、静的配列は配列長が固定された配列であり、配列を宣言するときに配列の長さを指定し、プログラムの実行中に変更できない必要があります.例:
int array1[10] = {0};//      10 int       ,       0
int array2[] = {1,2,3};//       3 int       ,         :1,2,3
const int ARRAY_SIZE = 100;
double array3[ARRAY_SIZE] = {0};//      100 int       ,     0

プログラムの実行時に配列の長さを変更しようとすると、次のようになります.
int array_size = 10;
int array[array_size] = {0};

では、コンパイラは必ずエラーを報告し、配列の長さが変数ではないことを示します.以上より,静的配列については,プログラムコンパイル中に配列に記憶空間を割り当てるなどの作業を完了する必要があり,これもプロセスプログラミング向けの体現である.
けっかん
配列の長さを明確にできないアプリケーションシーンでは、配列の長さをできるだけ大きくし、すべてのデータをできるだけ収容する唯一の方法があります.しかし、メモリの無駄になり、拡張性が低下し、不器用に見える可能性があります.
ダイナミック配列
定義#テイギ#
名前の通り、動的配列は、プログラムの実行中に配列の長さを変更することができる.すなわち,プログラムの実行中に配列の長さを指定して,異なるニーズを満たすことができる.では,配列長を動的に変更する目的をどのように実現するのか.C言語では,malloc関数とfree関数を用いてメモリ空間の動的割り当てを実現するのが一般的である.ただしC++では、より良いnew演算子とdelete演算子を使用して、上記の機能を完了することができます.対応するのは、malloc関数とnew演算子の役割は、スタック空間に新しいメモリ空間を開くことであり、free関数とdelete演算子は、必要に応じて、さっき開いたメモリ空間をタイムリーに解放し、メモリの漏洩を避けることです.次に,new演算子とdelete演算子を用いて動的配列を実現する方法を検討する.
動的配列の作成
new演算子とdelete演算子を使用して動的配列を作成する場合は、1、作成する配列の長さarray_の3つの情報を知る必要があります.size; 2、配列データのデータ型type_name; 3、いつメモリを解放しますか.例:
int* new_int_array = new int [10];//      10 int       ,          new_int_array
.....
delete [] new_int_array;//      ,           
double* new_double_array = new double [100];//      100 double       
......
delete [] new_double_array;//    

ふかさぶんせき
C言語のmalloc関数と同様に,new演算子を用いて新しい空間を開いた後,メモリ空間のヘッダアドレスを返す.したがって、ポインタ変数を使用してアドレスを受信する必要があります.また、ポインタ変数が指すデータ型は、newから出るメモリ領域で保存するデータ型と一致しなければならない.そうしないと、コンパイルできない.たとえば、次のようなものです.
double* new_array = new int [10];//     ,        
......
delete [] new_array;//        

配列要素へのアクセス
newを使用して動的配列を作成することに成功した後、ポインタと配列の関係を使用して配列内のデータを処理することができます.次のようになります.
int* array = new int [3];//      3 int     ,       array    
array[0] = 1;
array[1] = 2;
array[2] = 3;//         
cout << "      " << *(array + 0) << endl;//  1
cout << "      " << *(array + 1) << endl;//  2
cout << "      " << array[2] << endl;//  3
delete [] array;//         

注意事項
newとdeleteを使用して動的配列を作成および解放する場合は、1、deleteを使用してnewによって割り当てられた動的メモリを解放できないこと、2、deleteを使用して同じnewから出たメモリを複数回解放することはできません.3、new[]を使用して配列に記憶空間を割り当てる場合、delete[]を使用して解放する必要がある.4、空のポインタについてはdeleteを使用してリリースできます.
けっかん
静的配列に比べて、動的配列はより柔軟で、人間の思考にも合っている.しかし、特にnew以降、deleteがタイムリーでないとメモリ漏れが発生する危険性も増大します.
配列を使用する際の注意点
配列の下付き文字は0から
下に0と表示される配列要素は、配列の最初の要素を表します.
国境を越えた訪問を厳禁する.
配列の長さを超える空間にアクセスすると、配列が境界を越える現象が発生します.これは、非常に深刻なエラーを引き起こし、システムのクラッシュを引き起こす可能性があります.したがって、配列要素にアクセスする場合は、次のような境界を越えたアクセスを避ける必要があります.
int array[2] = {6,10};//     
cout << array[1] << endl;//  10
array[0] = 9;// 9           
array[2] = 10;//    

配列間の全体的な割り当て
静的配列間の全体的な割り当て
静的配列間では、次のような全体的な割り当ては許可されません.
int array1[3] = {10,20,30};
int array2[3] = {0};
array2 = array1;//  

割り当て操作は、次のように1つだけ行います.
int array1[3] = {10,20,30};
int array2[3] = {0};
for(int i = 0;i < 3;i++)
{
	array2[i] = array1[i];//    
}

ダイナミック配列間の全体的な割り当て
動的配列間では,全体的な付与操作を実現することができ,ここでの全体的な付与は,アドレスをコピーするだけであり,メモリには実際には1つの配列しか存在せず,複数のポインタ変数がこの配列を指しているだけである.次のようになります.
int* array1 = new int [10];
*(array1+0) = 1;
*(array1+1) = 2;
*(array1+2) = 3;
*(array1+3) = 4;
......
*(array1+9) = 10;//        
int* array2 = new int [10];
array2 = array1;//     ,  ,array2 array1         ,           
......
delete [] array1;
delete [] array2;

まとめ
本稿では,静的配列と動的配列のいくつかの知識,およびいくつかの注意点について主に説明した.C++では,テンプレートクラスvectorとテンプレートクラスarrayの2つの配列の代替品も提供され,後述する論文で専門的な学習を行う.