• 締切済み

二次元配列とポインタについてよくわかりません2

先ほどもしつもんして自分なりに改良をくわえたのですが 上手くいきません。 int main( void ) {  int i, j;  /*4 x 4 行列 A*/  double a[4][4];  double *pa;  /*4 x 4 行列 B*/  double b[4];  double (*pb)[4];  /*4 x 4 行列 C*/  double c[4];  double (*pc)[4];  pa = a;  pb = b;  pc = c;  printf("4 x 4 行列 Aの要素を入力してください>\n");  for(i = 0; i < 4; i++){   for(j = 0; j < 4; j++){    printf("A[%d,%d]=", i + 1, j + 1 );    scanf("%lf", (*(pa + i) + j)); }} printf("4 x 4 行列 Bの要素を入力してください>\n"); for(i = 0; i < 4; i++){  for(j = 0; j < 4; j++){   printf("B[%d,%d]=", i + 1, j + 1 );   scanf("%lf", &pb[i][j]); }} としたところ(途中までを表記してます)  pa = a;  pb = b;  pc = c; のところでコンパイル時に 警告で問題のあるポインタの変換とでます なぜおかしいのかまったくわからないので よければ教えてください

みんなの回答

  • kary
  • ベストアンサー率55% (10/18)
回答No.5

2次元配列とポインタ演算の関係を理解するのには、「配列の配列」という考え方と、「配列へのポインタ」という考え方の2つを理解する必要があるのではないのでしょうか。下記の書籍は、このようなことについて丁寧に説明してあると感じたものです。もし、機会があれば一度読んでみると参考になるかもしれません。 今回のご質問ですが、 double (*pa)[4]; double b[4][4]; double c[4][4]; のように直せばいいのではないでしょうか。(scanfの部分ですが、*(pa+i)+jで問題ないと私は思うのですが...。)

参考URL:
http://www.gihyo.co.jp/books/syoseki.php/4-7741-1142-2
  • wogota
  • ベストアンサー率42% (66/154)
回答No.4

double a[ 4][ 4]; と宣言することで、double型の変数が4つ格納できる 配列が4つ確保されことになります。 型としてはdouble (*)[ 4]と便宜的に同義となります。 ですので、 double *pa; でなく、 double (*pa)[ 4]; と宣言すれば、scanf関数で *(pa+ i)+ j をポインタとして渡すことは可能です。 一応、BorlandC++5という古い環境では、ポインタとして 渡せますが、今の環境ではわかりません。 が、#1,#2の方のおっしゃとおり、aとpaを用いるのでしょう。 scanfのポインタとして &(a[i][j]) を渡すようにしていれば、paを使う必要はありませんし、 単純な2次元として使用するのでしたら添え字の扱いを プログラマ側で整えてやれば、1次元配列でやっていけます。

  • yatokesa
  • ベストアンサー率40% (201/496)
回答No.3

>>for (i = 0; i < 4; i++) b[i] = malloc (sizeof(double) * 4); 間違えました。 for (i = 0; i < 4; i++) pb[i] = malloc (sizeof(double) * 4);

  • yatokesa
  • ベストアンサー率40% (201/496)
回答No.2

>scanf("%lf", (*(pa + i) + j)); 先ほどの質問にも書きましたが、これではだめですよ。またさらに状況が悪化しています。*(p + i) をアドレスとしてそれに +j してますから。 2次元の配列は表ですよね。今回の場合、i は縦、j は横の位置を指します。paを元にしてアドレスを変化させたい場合、pa[1][1]は iが1で jが1、pa + (i * 4) + j の位置です。これをscanf に渡します。同じ内容を printf したい場合はこのアドレスに * をつけます。*(pa + (i * 4) + j) です。 前後しますが、 > double b[4]; > double (*pb)[4]; : > pb = b; pb の領域には 4x4 =16個のdoubleの領域がなければなりません。しかしこれでは b[4] で4つのdoubleの領域と pbとしてdoubleの"アドレス"の領域が4つあるだけです。 ですから二次元分の領域(16個)を確保するには for (i = 0; i < 4; i++) b[i] = malloc (sizeof(double) * 4); とそれぞれに領域を割り当てなければなりません。 #蛇足ですが、流れを断ち切らないように同じ質問に補足という形で入れたもらうと良いと思います。

  • MovingWalk
  • ベストアンサー率43% (2233/5098)
回答No.1

先ほどってどれかわかりません。回答者に調べろってことですか? 4 x 4 行列A,B,Cなら  double a[4][4], b[4][4], c[4][4]; にすべきじゃないですか? (double b[4],c[4]にしているのは、どうして?) また、pa,pb,pc は何のために必要なんでしょうか? 単純に、scanf("%f", &a[i][j]);、scanf("%f", &b[i][j]); のようにすればいいだけじゃないですか。 尚、エラーの原因は、左辺と右辺の型が一致していないからです。 a: double **(= 二次元配列)、 pa: double * b,c:double *(= 一次元配列)、 pb,pc:double **(ポインタ変数の配列) また、scanf の引数の型もおかしいですよ。