キロスのゲーム日記

ゲーム、TCGなど趣味の話

C++言語で負の添字を持つ多次元配列の生成

C++の配列の添字は通常0から始まりますが、ポインタをちょっといじれば、負の添字を持つ一次元配列を生成できます。

サンプルコードを載せておきます。

#include <iostream>
#include <stdlib.h>

using namespace std;

#define NUM (2)

int main(){
  int i;
  int *A;
  
  try{
    //配列の動的確保
    A = new int[NUM+1];
  }catch(bad_alloc){
    cerr << "MEMORY ERROR." << endl;
    exit(1);
  }
  
  //成分の初期化
  for(i=0;i<NUM+1;++i){
    A[i]=i;
  }
  
  //成分の書き出し
  cout << "Before\n";
  for(i=0;i<NUM+1;++i){
    cout << "A[" << i << "]=" << A[i] << '\t';
  }
  cout << endl << endl;
  
  //負の添字を用意するために、配列を一つシフトさせる
  A=&A[1];
  
  //シフトさせた後の成分の書き出し
  cout << "After\n";
  for(i=-1;i<NUM;i++){
    cout << "A[" << i << "]=" << A[i] << '\t';
  }
  cout << endl;
  
  //メモリー解放
  delete[] &A[-1];
  
  return 0;
}


しかし、負の添字を持つ多次元配列の生成にはちょっと苦労しました。

一次元配列と同じように単純に添字をシフトさせていくと、多次元配列では中身がずれてしまいます。

そこで、配列の各次元に対応するポインタを仮置きしておくと、すべての添字を簡単にシフトさせられます。

言葉で説明するのは面倒なので、作ったサンプルコードを載せておきます。

配列の動的確保は各成分ごとに確保する簡単な方法でやっていますが、全成分をまとめて確保して並べ替える方法でも同じようにできます。

#include <iostream>
#include <stdlib.h>

using namespace std;

#define NUM (2)

int main(){
  int i,j,k;
  int ***A;
  
  try{
    //多次元配列の動的確保
    A = new int**[NUM+1];
    for(i=0; i<NUM+1; ++i){
      A[i] = new int*[NUM+1];
      for(j=0; j<NUM+1; ++j){
	A[i][j] = new int[NUM+1];
      }
    }
  }catch(bad_alloc){
    cerr << "MEMORY ERROR." << endl;
    exit(1);
  }
  
  //成分の初期化
  for(i=0; i<NUM+1; ++i){
    for(j=0; j<NUM+1; ++j){
      for(k=0; k<NUM+1; ++k){
	A[i][j][k] = i*100 + j*10 + k;
      }
    }
  }
  
  //成分の書き出し
  cout << "Before\n";
  for(i=0; i<NUM+1; ++i){
    for(j=0; j<NUM+1; ++j){
      for(k=0; k<NUM+1; ++k){
	cout << "A[" << i << "][" << j << "][" << k << "]=" << A[i][j][k] << '\t';
      }
      cout << endl;
    }
    cout << endl;
  }
  cout << endl;
  
  //第1成分の添字をシフトさせ、仮置き
  int ***tmp1 = &A[1];
  
  //第2成分の添字をシフトさせ、仮置き
  int **tmp2[NUM+1];
  for(i=0; i<NUM+1; ++i){
    tmp2[i] = &A[i][1];
  }
  
  //第3成分の添字をシフトさせ、仮置き
  int *tmp3[NUM+1][NUM+1];
  for(i=0; i<NUM+1; ++i){
    for(j=0; j<NUM+1; ++j){
      tmp3[i][j] = &A[i][j][1];
    }
  }
  
  //第1成分をシフト
  A = tmp1;
  
  //第2成分をシフト
  for(i=0; i<NUM+1; ++i){
    A[i-1] = tmp2[i];
  }
  
  //第3成分をシフト
  for(i=0; i<NUM+1; ++i){
    for(j=0; j<NUM+1; ++j){
      A[i-1][j-1] = tmp3[i][j];
    }
  }
  
  //シフトさせた後の成分の書き出し
  cout << "After\n";
  for(i=-1; i<NUM; ++i){
    for(j=-1; j<NUM; ++j){
      for(k=-1; k<NUM; ++k){
	cout << "A[" << i << "][" << j << "][" << k << "]=" << A[i][j][k] << '\t';
      }
      cout << endl;
    }
    cout << endl;
  }
  
  //メモリー解放
  for(i=-1; i<NUM; ++i){
    for(j=-1; j<NUM; ++j){
      delete[] &A[i][j][-1];
    }
    delete[] &A[i][-1];
  }
  delete[] &A[-1];
  
  return 0;
}
関連記事
関連するタグ PCC,C++プログラミング
[ 2015/10/02 03:30 ] PC C, C++ | TB(0) | CM(0)
コメントの投稿












管理者にだけ表示を許可する
トラックバック
この記事のトラックバックURL

プロフィール

キロス

Author:キロス
ゲームやTCG、その他日常生活で気になった事の話をします。
主にFFの話をするつもりですが、色々なネタを書くと思います。

検索フォーム
全記事表示リンク