第14講 フリーストア配列とCLI配列
第2話 フリーストア配列を関数に送る

前話解答例
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {
         int* a=new int[5];
         f(a);
         g(a);
         delete[] a;
      }
      void f(int* x){
         int i;
         for(i=0;i<5;i++)x[i]=i+1;
      }
      void g(int* x){
         int i;
         String^ w=L"";
         for(i=0;i<5;i++)w+=x[i].ToString()+L" ";
         label1->Text=w;
      }
ここで注目して頂きたいのは、ベクタのときは
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {
          vector<int> a(5);
          f(a);
          g(a);        
      }
      void f(vector<int> x){
         int i;
         for(i=0;i<5;i++)x[i]=i+1;
      }
      void g(vector<int> x){
         int i;
         String^ w=L"";
         for(i=0;i<5;i++)w+=x[i].ToString()+L" ";
         label1->Text=w;
      }
としたのでは、実行結果はとなってしまいました。
ベクタの場合は、正しい結果を得るには、
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {
          vetor<int> a(5);
          a=f(a);
          g(a);
      }
      vector<int> f(vector<int> x){
         int i;
         for(i=0;i<5;i++)x[i]=i+1;
         return(x);
      }
      void g(vector<int> x){
         int i;
         String^ w=L"";
         for(i=0;i<5;i++)w+=x[i].ToString()+L" ";
         label1->Text=w;
      }
としなければなりませんでした。つまり、関数fは最初のアドレスを返さなければならなかったのです。
それに対して、フリーストア配列の場合は、アドレスを返さないvoid型でもよいということです。
でもよいと書きましたのは、ベクタと同じようにアドレスを返すタイプにしてもよいからです。つまり、
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {
         int* a=new int[5];
         a=f(a);
         g(a);
         delete[] a;
      }
      int* f(int* x){
         int i;
         for(i=0;i<5;i++)x[i]=i+1;
         return(x);
      }
      void g(int* x){
         int i;
         String^ w=L"";
         for(i=0;i<5;i++)w+=x[i].ToString()+L" ";
         label1->Text=w;
      }
でも成功するということです。したがって、フリーストア配列の場合は、
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {
         int* a=new int[5];
         f(a);
         g(a);
         delete[] a;
      }
      void f(int* x){
         int i;
         for(i=0;i<5;i++)x[i]=i+1;
      }
      void g(int* x){
         int i;
         String^ w=L"";
         for(i=0;i<5;i++)w+=x[i].ToString()+L" ";
         label1->Text=w;
      }

private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {
          vetor<int> a(5);
          a=f(a);
          g(a);
         delete[] a;
      }
      vector<int> f(vector<int> x){
         int i;
         for(i=0;i<5;i++)x[i]=i+1;
         return(x);
      }
      void g(vector<int> x){
         int i;
         String^ w=L"";
         for(i=0;i<5;i++)w+=x[i].ToString()+L" ";
         label1->Text=w;
      }
のどちらでもよいのです。

次に2次元のフリーストア配列について考えてみましょう。
2次元にするには、
int** a=new int*[整数];
for(int i=0;i<整数;i++)a[i]=new int[整数];
のようにして宣言とサイズ(要素数=0を含めた添え字数)を行います。
新規プロジェクトを作り、フォームは前と同じにしてコーティングを次のようにしてみましょう。
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {
         int** a=new int*[5];
         int i,j;
         for(i=0;i<5;i++)a[i]=new int[6];
         for(i=0;i<5;i++)
           for(j=0;j<6;j++)
            a[i][j]=6*i+j+1;

         String^ w=L"";
         for(i=0;i<5;i++){
           for(j=0;j<6;j++)
             if(a[i][j]<10)
               w+=L"0"+a[i][j]+L" ";
             else
               w+=a[i][j]+L" ";
           w+=L"\n";

         }
         label1->Text=w;

         delete[] a;
       }
すると、実行結果はとなります。
さて、皆さん再び問題です。
前と同じようにデータ作成部分データ表示部分を独立させ関数に変更してください。



第11講第6話へ
 第12講第1話へ 第13講第10話へ 第14講第1話へ 第14講第3話へ



vc++講義第1部へ
vb講義へ
VB講義基礎へ
初心者のための世界で一番わかりやすいVisual Basic入門基礎講座へ
初心者のための世界で一番わかりやすいVisual C++入門基礎講座へ