動的に生成したいくつかの配列それぞれにアクセスするのにポインタを使おうという試みです。
ちなみに配列の個数は動的、配列のサイズは静的という前提で話を進めます。
##ポインタ配列の使い方
#include <iostream>
using namespace std;
int **seq_array; //ポインタ配列
int main(void){
int p1[3] = {10,20,30};
int p2[3] = {40,50,60};
int p3[3] = {70,80,90};
seq_array = new int*[3]; //ポインタの配列を作成
//配列の先頭ポインタアドレスを格納
seq_array[0] = p1;
seq_array[1] = p2;
seq_array[2] = p3;
cout << seq_array[0]<<endl; //配列p1の先頭アドレス
cout << seq_array[1]<<endl;
cout << seq_array[2]<<endl;
cout << *seq_array[0]<<endl; //配列の先頭要素にアクセス
cout << *seq_array[1]<<endl;
cout << *seq_array[2]<<endl;
cout << *(seq_array[0]+1)<<endl; //ポインタインクリメントで配列の任意の要素にアクセス
cout << *(seq_array[0]+3)<<endl; //配列外へアクセスすると初期化されてない値が入る
}
結果
seq_array[0] : 10 20 30
seq_array[1] : 40 50 60
seq_array[2] : 70 80 90
Program ended with exit code: 0
まずポインタを格納する配列はポインタのポインタとして宣言します。
newでint型の配列を作成し、各配列への先頭ポインタを格納します。
seq_array[0]、p1ともにint型です。
配列の要素を参照する際には、まず
*seq_array[0]
で配列の先頭できます。seq_array[0]は配列p1の先頭ポインタを指すので、これにインクリメントすることで任意の箇所の要素を取り出せます。
*(seq_array[0]+1)
##動的に生成した配列
#include <iostream>
using namespace std;
int **seq_array; //ポインタ配列
int n=10;
int main(void){
int num = 3;//配列の数が決定
int elm_num = 3; //配列の要素数が決定
seq_array = new int*[num];//ポインタの配列を作成
//配列の先頭ポインタアドレスを格納
for(int i=0; i<num; i++){
//先のコードのp1,p2,p3は全て配列seq_arrayの配列とみなす
seq_array[i] = new int [elm_num]; //ここで配列を作る
for(int j=0; j<elm_num; j++){
*(seq_array[i]+j) = n; //i番目の配列の添字jの要素に対して代入
n += 10;
}
}
for(int i=0; i<num; i++){
cout << "seq_array[" << i << "] : ";
for(int j=0; j<elm_num; j++){
cout << *(seq_array[i]+j) << " ";
}
cout << endl;
}
}
結果
seq_array[0] : 10 20 30
seq_array[1] : 40 50 60
seq_array[2] : 70 80 90
Program ended with exit code: 0
図がかければよかったんですが、
seq_array というポインタの入った配列を根っことして、
seq_array[i] で表される配列の先頭ポインタから、i番目の配列の要素にポインタでアクセスするという試みです。
もともと、p1,p2...といった変数名では、配列それぞれにfor文を回す時にどうしよう…となってしまったので、それなら配列使えば、ということでこういうことをしていたら若干複雑になってしまいました…。
そもそもポインタのポインタに対してあまり深く理解していなかったのでいい勉強にもなりました。
書き終わって思いついたけど、配列数や配列の要素数が後に決まる場合ってどうするんだろう。
可変配列に対してはやはりvectorを使うのが丸いのかな。