Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
  • 締切済み

行列の積を関数を使って求める・・?

2つの行列の行と列を入力し、積を計算するプログラムを関数を使って書きたいのですが、上手く行きません。どこをどのように直したらよいか教えてください!お願いします!! 以下が私が書いたプログラムです。 #include<stdio.h> #define NUMBER 10 int first(int x1,int x2,int y1,int y2,int i,int j,int k) { int a[NUMBER][NUMBER] = {0}; int b[NUMBER][NUMBER] = {0}; int c[NUMBER][NUMBER] = {0}; do{ printf("2つの行列の行と列を入力してください\n"); scanf("%d", &x1); scanf("%d", &x2); scanf("%d", &y1); scanf("%d", &y2); if(x1 != y2){ printf("行列の積は計算できません\n"); } }while(x1 != y2); printf("行列Aの要素を入力してください\n"); for(i=0; i<x1; i++){ for(j=0; j<x2; j++) scanf("%d", &a[i][j]); } printf("行列Bの要素を入力してください\n"); for(j=0; j<y1; j++){ for(k=0; k<y2; k++) scanf("%d", &b[j][k]); } } int second(int x1,int x2,int y1,int y2,int i,int j,int k) { int a[NUMBER][NUMBER] = {0}; int b[NUMBER][NUMBER] = {0}; int c[NUMBER][NUMBER] = {0}; for(i=0; i<x1; i++){ for(k=0; k<y2; k++){ for(j=0; j<x2; j++) c[i][k] = c[i][k] + a[i][j]*b[j][k]; } } for(i=0; i<x2; i++){ for(k=0; k<y2; k++) printf("%3d", c[i][k]); printf("\n"); } } int main(void) { int a[NUMBER][NUMBER] = {0}; int b[NUMBER][NUMBER] = {0}; int c[NUMBER][NUMBER] = {0}; printf("行列の積を計算します\n %d\n", first(x1,x2,y1,y2,i,j,k)); printf("行列Aと行Bの積は\n %3d",second(x1,x2,y1,y2,i,j,k)); }

みんなの回答

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.7

>初期化してみましたが上手く行きませんでした・ int a[NUMBER][NUMBER] = {0}; int b[NUMBER][NUMBER] = {0}; int c[NUMBER][NUMBER] = {0}; の部分を関数の外に出してください。 それぞれの配列でのやりとりをしていないので、 同じ配列をいじるというプログラムになっていますが、 現状は、別々に確保されています。

yellowtail-ayari
質問者

お礼

ありがとうございます。 関数の外に出して定義しました。

すると、全ての回答が全文表示されます。
  • ency
  • ベストアンサー率39% (93/238)
回答No.6

No5 bf109e さんに補足です。 No5 bf109e さんのご回答の、first()、second() のそれぞれの引数を、以下の3つのうちのいずれかに変更してみてください。 # a だけでなく、b も同様です。 int a[][] →int a[NUMBER][NUMBER]  int a[][NUMBER]  int (*a)[][NUMBER] 一番目は、配列をそのまま渡すイメージでわかりやすいと思います。 二番目は、配列をそのまま渡すイメージではありますが、前の要素数が空っぽになっています。 要するに書いても意味がないってことです。 その理由が三番目です。 これは「配列を指すポインタ」の定義になります。 配列はその先頭要素を指すポインタに読み替えられるのはご存知でしょうか。 配列の配列でも同様の読替えが起こります。 参考URL の No5 (私のアドバイスですけど。。。) にも書いていますので、そちらもご参照ください。 # 少々長いのはご勘弁ください。。。 これでいかがでしょうか。

参考URL:
http://oshiete1.goo.ne.jp/kotaeru.php3?q=1440162
yellowtail-ayari
質問者

お礼

ありがとうございます。 配列のところでつまづいたままなのできちんと勉強しなおしたいと思います。

すると、全ての回答が全文表示されます。
  • bf109e
  • ベストアンサー率0% (0/0)
回答No.5

#include<stdio.h> #define NUMBER 10 void first(int a[][], int b[][]) { /*行列a,bの要素を入力*/ second(a, b, x1, x2, y1, y2); } void second(int a[][], int b[][], int x1, int x2, int y1, int y2) { int c[NUMBER][NUMBER] = {0}; /*a,bの積を計算,表示*/ } int main(void) { int a[NUMBER][NUMBER] = {0}; int b[NUMBER][NUMBER] = {0}; printf("行列の積を計算します\n"); first(a,b); return 0; } 大まかな形はこんなもんでどうでしょう。

yellowtail-ayari
質問者

お礼

ありがとうございます^^ 大まかに参考にさせてもらいましたが、やっぱり上手くいきませんでした・・。

すると、全ての回答が全文表示されます。
  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.4

#1さんの様に、 式中にc[i][j]を埋め込まないで、一時変数を使うというのは、 ループの中で、[i][j]によるアドレスの計算をいちいちさせないという効果があります。 コンパイラによっては自分で最適化してくれるかもしれませんが、書いても損にはなりません。(むしろ推奨です) ただ、使う前に初期化しないといけないのは同じです。

yellowtail-ayari
質問者

お礼

ありがとうございます^^ 式中にc[i][j]を埋め込まないで一時変数をおくといいのですね。初期化ということはどこかでw=0と書くということで良いのでしょうか? 参考になりました^^

すると、全ての回答が全文表示されます。
  • k_riv
  • ベストアンサー率57% (105/183)
回答No.3

#2さんに賛成。 よく考えたら、同じでした。 ごめんなさい。

すると、全ての回答が全文表示されます。
  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.2

c[i][k]がちゃんと0で初期化されていないのが原因だと思います。 適当なタイミング for(j=0; j<x2; j++)の前で c[i][k]=0をしてやればいいような気がします

yellowtail-ayari
質問者

お礼

ありがとうございます! 指定していただいた場所で初期化してみましたが上手く行きませんでした・・でも初期化のことは今後の参考にさせていただきます^^

すると、全ての回答が全文表示されます。
  • k_riv
  • ベストアンサー率57% (105/183)
回答No.1

for(j=0; j<x2; j++) c[i][k] = c[i][k] + a[i][j]*b[j][k]; } ここで、足し過ぎてませんか? 変数をもうひとつ用意して、 w=w + a[i][j]*b[j][k]; } c[i][k] = w; では、いかがでしょう。

yellowtail-ayari
質問者

お礼

ありがとうございます! 参考にさせていただきました^^

すると、全ての回答が全文表示されます。

関連するQ&A