not good but great

プログラミング、アート、映画・本の感想について書きます。

ポインタ配列を使って擬似的な二次元配列を生成する

ポインタのポインタがわからなかった

http://openframeworks.cc/tutorials/first%20steps/003_ooops_object_oriented_programming.html
チュートリアルをやっていて、ポインタのポインタが出てきました。

ofBall** myBall;

なんじゃこれは・・・と思い、ポインタのについ復習しました。

ポインタの配列

複数の文字をchar型の2次元配列で示します。

char greeting[3][7] = {"Hello","Ohayo","Byebye"};

これをポインタを使って書き直します。

const static char *greeting[] = {"Hello","Ohayo","Byebye",NULL};

配列の数は勝手に数えてくれるので省略できます。greeting[0]は"Hello"の先頭アドレスを示しています。

・参考
C言語講座:ポインタの配列(1)

配列の動的確保

・参考
http://www.flow.cs.is.nagoya-u.ac.jp/hamada/programming/cpp5.html

配列のサイズは定数で定義

double a[10];	// OK

int n;
cin >> n;	// キーボードから入力
double b[n];//コンパイルエラー

変数で定義しようとするとエラーが出ます。たぶんこれはいきなり変数で配列を宣言されても、メモリを確保、用意できていないからエラーになるんだと思います。

だからメモリを事前に確保する必要があります。

#include <stdlib.h>
int n;
double * b;
scanf( "%d", &n );
b = (double *)malloc( sizeof( double ) * n );	// b を確保

参考ページからのコピペになってしまいますが、上のようにmallocを使えばメモリを確保できます。double型の数だけメモリを確保して、戻り値がvoidなので、doubleにキャストしています。

cppではnewする

cppではmallocの代わりにnew[]演算子を使います。

int n;
cin >> n;
double * b = new double[n];	// b を確保

簡単ですね。

二次元配列をつくる

double **b = new double[n][m];

このようには書けません。newできるのは1次元配列のみみたいです。

int n, m;
/* n と m を決定 */
double ** a = new double*[n];
for( int i=0; i<n; i++ ) {
    a[i] = new double[m];
}

2次元配列をnewできないので、代わりにポインタ配列を用います。これがポインタのポインタの正体でした。

チュートリアルのコード

ofBall** myBall;

ポインタを入れるポインタを宣言します。

擬似的な2次元配列

myBall = new ofBall*[nBalls];

for(int i = 0; i < nBalls;i++){
    float x = 20 + (100 * i);
    float y = 20 + (100 * i);
    int dim = 10 + (i * 10);
    
    myBall[i] = new ofBall(x,y,dim);
    
}

setup()の中で、上のように、擬似的な2次元配列を生成しています。ポインタの配列の中にまたポインタが入っている状態(ポインタ配列)になります。