• ベストアンサー

動的配列の受け渡しについて

動的に定義した2次元配列を受け渡す方法がわからなくて困ってます。 配列に-1以外が入っている場合の行数を数えるプログラムを作成しています。 しかし、コンパイルすると下のエラーが出てコンパイルできません。 error:cannot convert 'long int **' to 'long int (*)[2] for argument '1' to 'long int count_line(long int (*)[2])' #include <stdio.h> long count_line(long arrau[][2]); int main(void){   long** test = new long* [100];   for(long num1=0 ; num1<100 ; num1++){     test[num1] = new long [2];   }   for(int i=0 ; i<100 ; i++){     test[i][0]=-1;     test[i][1]=-1;   }   for(int num2=0 ; num2<10 ; num2++){     test[num2][0]=1;     test[num2][1]=1;   }   int x=0;   x = count_line(test);   printf("x=%d\n",x); } long count_line(long array[][2]){   long count=0;   long end=0;   long roop=0;   while(end!=-1){     if(array[roop][1]!=-1){       count++;     }     end=array[roop][1];     roop++;   }   return(count); } どなたかお助けをー(T_T)

質問者が選んだベストアンサー

  • ベストアンサー
  • chie65535
  • ベストアンサー率43% (8518/19363)
回答No.4

>long count_line(long arrau[][2]); 配列arrauは、メモリ上に以下のように並んでいる事になります。 arrau {long long} arrau+?{long long} arrau+?{long long} arrau+?{long long} arrau+?{long long} arrau+?{long long} (以下略、個数不明) >  long** test = new long* [100]; 一方、testは、以下のようになります。 test{long *(どこかのアドレス1を指している)} どこかのアドレス1 {long *(どこかのアドレス2を指している)} どこかのアドレス1+?{long *(どこかのアドレス3を指している)} どこかのアドレス1+?{long *(どこかのアドレス4を指している)} (以下、100個、繰り返し) どこかのアドレス2{long long} どこかのアドレス3{long long} どこかのアドレス4{long long} (以下、不連続にバラバラに100個存在する) 「どっからどう見ても、メモリ上のデータの並び方が違う」とは思いませんか? コンパイラは「データの並びが全然違うから、引数を言われた形には変換できません。無理っす」って言ってエラーを吐きます。 >どなたかお助けをー(T_T) 「引数の型」と「実際に引数に渡している変数の型」を一致させて下さい。 そうすれば、エラーもワーニングも消えます。

tateto2009
質問者

お礼

詳しい説明ありがとうございますm(_ _)m なるほど、ポインタのポインタ?の理解が足りてませんでした。 count_line(long **array)にすることで、「引数の型」と「実際に引数に渡している変数の型」を一致させることができたのですね。 エラーもワーニングも消すことができました。 本当にありがとうございました。

その他の回答 (3)

  • googoo131
  • ベストアンサー率45% (5/11)
回答No.3

後一つ追記ですが、 整数値変数を初期化する必要はないです。 int x=0; ではなく int x; でOKです。

tateto2009
質問者

お礼

なるほど。 今まで、変数定義するときは全部「=0」をつけてました^^; これからは「int=x;」でいきます。

  • googoo131
  • ベストアンサー率45% (5/11)
回答No.2

関数の引数定義が間違ってます。 long count_line(long array[][2]) ではなく、 long count_line(long **array) です。 引数を修正してこのプログラムコンパイルしてみると 警告は出ますが、プログラム自体は動くと思います。

tateto2009
質問者

お礼

指摘していた頂いた通りに修正しコンパイルしましたら、 警告も何も出ずにコンパイルできました^^ プログラムも正常に動作しています。 ありがとうございました~m(_ _)m

  • koko_u_u
  • ベストアンサー率18% (216/1139)
回答No.1

>しかし、コンパイルすると下のエラーが出てコンパイルできません。 そのエラーメッセージの通りです。 あなたの宣言した long count_line(long arrau[][2]); の引数は 2次元配列が「みっしり」並んでいることを想定していますが、 実際に確保した動的配列はそうではないですよね。

tateto2009
質問者

お礼

なるほど、確かにarray[][2]だと静的に確保した場合ですよね^^; ん~、同じ指定方法ですとダメみたいですねorz

関連するQ&A

  • 配列のサイズを動的に拡張

    お世話になっております。 配列のサイズを動的に拡張について悩んでおります。例えばint x[5]という配列があって、データが埋まったら動的にx[6]にする・・ っといったものです。自分で試行錯誤した結果、以下のようなプログラムを作成しました。 int *data,count=0,num=10;// グローバル変数 // 配列にデータを加える関数add void add(int t){  if(count+1>num){ // サイズを超えたら配列をサイズを+1    int i,*tmp_data;    tmp_data = new int [count];    for(i=0;i<num;i++) tmp_data[i] = data[i]; // 一時的に保存    delete[] data; // 古いのを消す    data = new int [num+1]; // 新しく作る    for(i=0;i<num;i++) data[i] = tmp_data[i]; // 新しいのにコピー    num+=1; // 最大値をプラス    data[count]=t;    delete[] tmp_data;  }  else data[count]=t;  count++; // 入力されたカウントをプラス } main関数内で、data = new int [10];と宣言し、add(3);のように使用しています。またnewのメモリ確保のエラー処理は省いております。 動くことは動くのですが・・ご覧の通り、グローバル変数が3つになり、データをコピーしたりと、複雑になってしまいました。 もっと簡単に出来るのでは・・っと思い質問させて頂きました。 こうすれば、もっと簡単になるよ!など。。ご回答頂ければ幸いです。

  • 二次配列のqsort

    二次配列のqsortについて分かる方に教えて頂きたいのですが 一段落のプログラムを載らせていただきました.count3[j][i]をバブルソートで降順でやってみましたが高速が要求されるため,qsortを使ってやり直したいのですが (ちなみにcount1[j][i],count2[j][i]は前で定義してあります.count4[j][i]にはiの順番を記憶するための二次配列です)  ぜひともよろしくおねがいします. int ind_near_search(int j,int t) { int i,var_num,count3[IND][VAR],count4[IND][VAR],temp1,temp2,num=0,m=0; for(i=0;i<VAR;i++){ if(individual[j].x[i]==1){ //変数が1と0の場合分け count2[j][i]=t-count[j][i]; }else{ count2[j][i]=count[j][i]; } if(individual[j].x[i]==1){ //全てcount3に値を入れる count3[j][i]=count2[j][i]; }else{ count3[j][i]=count[j][i]; } } for(i=0;i<VAR;i++){ count4[j][i]=num++; } for(m=0;m<VAR-1;m++){ for(i=0;i<VAR;i++){ //バブルソートにより降順に並べ換え if(count3[j][i]<count3[j][i+1]){ temp1=count3[j][i]; count3[j][i]=count3[j][i+1]; count3[j][i+1]=temp1; temp2=count4[j][i]; //count4にはcount3の並べ替え後の対応する番号を入れる count4[j][i]=count4[j][i+1]; count4[j][i+1]=temp2; } } } for(i=0;i<VAR;i++){ var_num=count4[j][i]; //count4の大きい順番からその番号をvar_numに渡す if(individual[j].x[var_num]==0){//0と1の場合分け individual[j].x[var_num]=1; }else{ individual[j].x[var_num]=0; }

  • 配列

    public void test(int[] x){ ... } というメソッドに配列を渡したいとき、 test(new int[5]); は可能ですが、 int[] a = {0,1,2,1,0} という書式が可能なことから、 test( {0,1,2,1,0} ); としてみたのですが、コンパイルでひっかかります。 {}による配列生成は初期化のみに限定されているのでしょうか。 値の入った配列をこのtestに入れてやりたい場合は、 int[] a = {0,1,2,1,0}; test(a); としていかないといけないのでしょうか。

    • ベストアンサー
    • Java
  • 2次元配列のポインタ

    整数型行2列2の2次元配列の[1][0]は、ポインタでは3になるとおもっているのですが、ちがったでしょうか? 下記のソースでエラーが出ていて困っています。 void main() { int array[2][2] = { { 9, 9 }, { 9, 9 } }; int num=2, j,i; *(array + 3) = 0; for (i = 0; i < num; i++) { for (j = 0; j < num; j++) { printf("%d", array[i][j]); } puts(""); } } 99 09 と表示させたいのですが、どこに間違いがあるのでしょうか?

  • C#で、引数にクラスの配列の参照パラメータを渡したい

    C#始めて3日目ですが、そろそろ挫折しそうです。 以下のクラス class Test{ int num; public Test(){ num = 0 }; ~Test(){}; public void set(int n){ num = n; } public int get(){ return num; } } があり、 void kakikae(Te [] t){ for(int i =0; i < 10; i++){ t[i].set(i); } } Test [] test = new Test[10] = { new Test, new Test, new Test, new Test, new Test, new Test, new Test, new Test, new Test, new Test }; kakikae(test); とした時に、test[0]からtest[9]まで 1,2,3,4,5,6,7,8,9 の値が入っている事がしたいのです。 要は、クラスの配列のポインタを渡して、相手側の関数で書き方内容が、関数から戻った時も値渡しでなく 参照渡しのように値が変わって戻ってきて欲しいです。 配列の仕組み、クラスの仕組み、パラメータの仕組みが 分からず、ここから進みません。 1から勉強できるC#の参考書も探しています。

  • 配列のキー取得

    現在の$str配列には、下記のようになっています。 Array ( [9] => test [5] => aaa [7] => bbb) print_r(array_keys($str)); とすると下記のように配列のキー値がわかりますが、 Array ( [0] => 9 [1] => 5 [2] => 7) キーを下記のように一つづつほかの配列に代入したい場合はどのようにしたらいいのでしょうか? for($i=0;$i<count($str);$i++){ $new_str[$i]=キーを取得する関数; } ご教授お願いいたします。

    • ベストアンサー
    • PHP
  • 配列の受け渡し

    こんばんは。 あるページで使用した配列を他のページでも使いたいのですが、 こういう配列を格納した変数の受け渡しって出来るのでしょうか? 普通の変数のデータを受け渡したかったら <input type="hidden" />で直接valueに変数の値を入れれば良いですが、 配列だと自分では以下のように愚直にやる方法しか分かりません。 もっとちゃんと渡せる方法ってあるのでしょうか? <?$a=array(1,2,3,4,5);?> <? for($i=0;$i<count($aaa);$i++){ ?> <input type="hidden" value="<?=$aaa[$i]?>" name="hoge[]"/> <?}?>

    • ベストアンサー
    • PHP
  • 動的に確保した配列のファイルへの書き出し

    動的に確保した配列を、ファイルに書きだそうとしています。 int i, arraysize = 10; int **array; array = new int*[ arraysize ]; for (i = 0 ; i < arraysize ; i++) array[ i ] = new int [ arraysize ]; ofstream out("filename", ios::out | ios::binary); out.write((char *) array, sizeof( array )); これでは array のポインタが書き込まれるだけ、なのかな ? ということで、配列を書き込む目的を果たせておりません。このように動的に確保した多次元配列 (要素数は既知) をファイルに書き込むためにはどうすればよろしいでしょうか。

  • 配列の中にもう1度配列を宣言?

    今知人から昔に貰ったソースプログラムを読んでいます 自分の知識不足でどのようになっているのかわからない箇所があるので教えていただけると助かります 一部抜粋 test = new Array() for(i=0; i<9; i++) { test[ i ] = new Array() } 上記のコードは配列の中にまた更に配列を作成していると言うことで2次元配列なのでしょうか? わざわざこのような書き方をしたと考えられる事がありましたら教えていただけると助かります

    • ベストアンサー
    • Flash
  • C言語 ソートについて

    #include <stdio.h> #include <stdbool.h> #define NUM_ARRAY 4 #define NUM_DATA 5 int count_swap = 0; // 交換回数 int count_comparison = 0; // 比較回数 void selection_sort(int a[], int n) { } int main(void) { int data[NUM_ARRAY][NUM_DATA] = {{9, 7, 5, 6, 8}, {9, 8, 7, 6, 5}, {5, 6, 7, 8, 9}, {5, 6, 8, 7, 9}}; for (int i = 0; i < NUM_ARRAY; i++) { count_swap = 0; count_comparison = 0; int d[NUM_DATA]; copy_array(data[i], d, NUM_DATA); // 配列のコピー printf("----------------\n"); print_array(d, NUM_DATA); // ソート前の配列の表示 selection_sort(d, NUM_DATA); // 挿入ソートの実行 print_array(d, NUM_DATA); // ソート後の配列の表示 printf("比較回数: %d\n", count_comparison); // 比較回数の表示 printf("交換回数: %d\n", count_swap); // 交換回数の表示 } } 上の雛形を使って選択ソートを実行するという問題なのですが途中までそれっぽいのは出来たのですが上手くいかないので解答をお願いします。 下に自分が今書いているものを置いておきます。 #include <stdbool.h> #include <stdio.h> #define NUM_ARRAY 4 #define NUM_DATA 5 int count_swap = 0; int count_comparison = 0; void swap(int d[], int i, int j) { count_swap += 1; printf("swap a[%d] = %d, a[%d] = %d\n", i, d[i], j, d[j]); int temp = d[i]; d[i] = d[j]; d[j] = temp; } void copy_array(int *a, int *b, int n) { for (int i = 0; i < n; i++) { b[i] = a[i]; } } void print_array(int d[], int n) { for (int i = 0; i < n; i++) { printf("%d ", d[i]); } printf("\n"); } bool compare(int d[], int i, int j) { count_comparison += 1; printf("compare a[%d] = %d, a[%d] = %d\n", i, d[i], j, d[j]); if (d[i] > d[j]) { return true; } else { return false; } } void selection_sort(int d[], int n) { int min; for (int i = 0; i < n - 1; i++) { min = i; for (int j = i + 1; j < i; j++) { if (compare(d, min, j)) { min = j; } } swap(d, i, min); print_array(d, n); } } int main(void) { int data[NUM_ARRAY][NUM_DATA] = { {9, 7, 5, 6, 8}, {9, 8, 7, 6, 5}, {5, 6, 7, 8, 9}, {5, 6, 8, 7, 9}}; for (int i = 0; i < NUM_ARRAY; i++) { count_swap = 0; count_comparison = 0; int d[NUM_DATA]; copy_array(data[i], d, NUM_DATA); // 配列のコピー printf("----------------\n"); print_array(d, NUM_DATA); // ソート前の配列の表⽰ selection_sort(d, NUM_DATA); // 挿⼊ソートの実⾏ print_array(d, NUM_DATA); // ソート後の配列の表⽰ printf("⽐較回数: %d\n", count_comparison); // ⽐較回数の表⽰ printf("交換回数: %d\n", count_swap); // 交換回数の表⽰ } }

専門家に質問してみよう