C言語で行列の積を計算するプログラム

このQ&Aのポイント
  • C言語のプログラムで行列の積を計算する方法について解説します。
  • 行列の積を計算する際に、初期化のタイミングを間違えると実行結果が異なる場合があります。
  • 正しい初期化の方法を確認し、問題なく行列の積を計算できるようにしましょう。
回答を見る
  • ベストアンサー

C言語です

#include<stdio.h> int main(void){ int matA[4][4], matB[4][4], matC[4][4]; int i, j, k; /* 行列A の読み込み */ for(i = 0; i < 4; ++i){ for(j = 0; j < 4; ++j){ scanf("%d",&matA[i][j]); } } /* 行列B の読み込み */ for(i = 0; i < 4; ++i){ for(j = 0; j < 4; ++j){ scanf("%d",&matB[i][j]); } } /*行列の積の計算*/ for(i = 0; i < 4; ++i){ for(j = 0; j < 4; ++j){ matC[i][j]=0; /*初期化が必要*/ for(k = 0; k < 4; ++k){ matC[i][j]+=matA[i][k]*matB[k][j]; } } } /*結果の表示*/ for(i = 0; i < 4; ++i){ for(j = 0; j < 4; ++j){ printf("%d\t",matC[i][j]); } printf("\n"); } return 0; } このプログラムについてですが、 /*行列の積の計算*/ for(i = 0; i < 4; ++i){ for(j = 0; j < 4; ++j){ matC[i][j]=0; /*初期化が必要*/ for(k = 0; k < 4; ++k){ matC[i][j]+=matA[i][k]*matB[k][j]; } } } この部分の初期化がfor(k = 0; k < 4; ++k){の部分の後ろだったら 実行結果が異なります。 なぜ、 for(k = 0; k < 4; ++k){ matC[i][j]=0; /*初期化が必要*/ この順番だといけないんですか?

noname#181900
noname#181900

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

  • ベストアンサー
  • hirotn
  • ベストアンサー率59% (147/246)
回答No.1

+= 演算子を使っているので、積算しています(計算結果をmatCに足し続ける) しかし、for(k = 0; k < 4; ++k){のループの度にmatCを初期化してしまうので、最後の掛け算しか残っていないことになる。 と読めます。

その他の回答 (3)

  • KEIS050162
  • ベストアンサー率47% (890/1879)
回答No.4

計算の過程が知りたいとき、部分的にデバッグ用に、printf() 文とgetch() などを組み合せて追加し、処理の過程などを確認してみると良いでしょう。デバッグが終わったら、コメントにしてしまえばOKです。 for(k = 0; k < 4; ++k){    matC[i][j]+=matA[i][k]*matB[k][j];    printf( "matc{ %d ][ %d ] = %d\n". i, i, matc[i][i] );    getch(); デバッグが終わったら、コメントにする。 //   printf( "matc{ %d ][ %d ] = %d\n". i, i, matc[i][i] ); //   getch(); 色んな場所に上記の様なprintf()を入れ込んで試してみてください。

  • Wr5
  • ベストアンサー率53% (2177/4070)
回答No.3

ステップ実行のやりかたとか調べるか、pritnf()などで変数の内容出力してみるとかしないんですか? 質問乱立しまくりのようですが……。 for(i = 0; i < 4; ++i){  for(j = 0; j < 4; ++j){   matC[i][j]=0; /*初期化が必要*/   for(k = 0; k < 4; ++k){    matC[i][j]+=matA[i][k]*matB[k][j];   }  } } を for(i = 0; i < 4; ++i){  for(j = 0; j < 4; ++j){   for(k = 0; k < 4; ++k){    matC[i][j]=0; /*初期化が必要*/    matC[i][j]+=matA[i][k]*matB[k][j];   }  } } にしたら、結果が異なるのはな~んでだろ~? って質問でいいんですかね? for(k = 0; k < 4; ++k)のループで matC[i][j]=0;により0が入ります。 次にmatC[i][j]+=matA[i][k]*matB[k][j];の演算結果を代入します。 次のループに入って、 matC[i][j]=0;により0が入ります。 # つまり「以前の演算結果はご破算にしろ」と言っています。 それを繰り返して、結果として有効になるのは最後の演算結果だけです。 「そうしろ」というコードなのですから、CPUは言われたとおりに忠実に実行しただけです。

  • hirotn
  • ベストアンサー率59% (147/246)
回答No.2

matC[i][j]+=matA[i][k]*matB[k][j];を、 matC[i][j]=matA[i][k]*matB[k][j]; として試行してみてください。実行結果が異なる場合とおなじになりませんか?

関連するQ&A

  • c言語 行列の積に関して

    <問>  4行3列の行列aと3行4列の行列bの積を、4行4列の行列cに格納する関数を作成せよ。  void mat_mul(const int a[4][3], const int b[3][4], int c[4][4]) 入門レベルのスキルしかありません。 上手く行列の積のプログラムが組めません。 行列の積の計算結果が何も出てきません。 どの様にしたら良いかご指導の程、宜しくお願いします。 <プログラム>  void mat_mul(const int a[4][3], const int b[3][4], int c[4][4]) { int i, j, k; for (i = 0; i < 4; k++) { for (j = 0; j < 4; i++) for (k = 0; k < 3; j++) c[i][j] = c[i][j] + (a[i][k] * b[k][j]); } } void mat_print(const int m[4][4]) { for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) printf("%4d", m[i][j]); putchar('\n'); } } int main(void) { int i, j ,k; int tensu1[4][3]; int tensu2[3][4]; int seki[4][4]; for(i = 0; i < 4; i++) { for (j = 0; j < 3; j++) { scanf("%d", &tensu1[i][j]); } putchar('\n'); } for(i = 0; i < 3; i++) { for(j = 0; j < 4; j++){ scanf("%d", &tensu2[i][j]); } putchar('\n'); } putchar('\n'); mat_mul(tensu1, tensu2, seki); puts("行列の積"); mat_print(seki); return 0; }  

  • c言語のプログラムで行列の積を計算する

    指定された行・列数(それぞれ10以下とする)の行列 X, Y の積 Z = X × Y を求めるプログラムを作成せよ.行列の要素はすべて整数とする. このプログラムで行と列の成分を入力するときに、1列になってしまうのですがどうしたらちゃんと入力できますか? int main(void) { double A[10][10]; double B[10][10]; int i,j,m,n,p,k; printf("行列xの行数は?:"); scanf("%d",&m); printf("行列xの列数(行列yの行数)は?:"); scanf("%d",&n); printf("行列yの列数は?:"); scanf("%d",&p); printf("行列xを入力してください。\n"); for (i = 0; i < m; i++) { for (j = 0; j < n; j++) { scanf("%d", &A[i][j]); } } printf("行列yを入力してください。\n"); for (i = 0; i < n; i++) { for (j = 0; j < p; j++) { scanf("%d", &B[i][j]); } }

  • c言語で行列の積の値を求める

    行列の成分を入力した後に、 入力された行列は X = 1 2 3 4 5 6 7 8 9 10 11 12 Y = 1 5 2 6 3 7 4 8 のように表示して、(上の数字は適当です。) 行列 X と行列 Y の積を求めて結果を表示するプログラムが作りたいのですが、上手く表示できなくて困っています。 #include <stdio.h> int main(void) { double A[10][10]; double B[10][10]; double C[10][10]; int i,j,m,n,p,k; printf("行列xの行数は?:"); scanf("%d",&m); printf("行列xの列数(行列yの行数)は?:"); scanf("%d",&n); printf("行列yの列数は?:"); scanf("%d",&p); printf("行列xを入力してください。\n"); for (i = 0; i < m; i++) { for (j = 0; j < n; j++) { scanf("%d", &A[i][j]); } } printf("行列yを入力してください。\n"); for (i = 0; i < n; i++) { for (j = 0; j < p; j++) { scanf("%d", &B[i][j]); } } この後にどうすればいいのか教えてください。 よろしくお願いします。

  • c言語についての質問です。

    expected expression before ‘<’ token このエラーはどういう意味ですか? このプログラムで出てくるんですが・・・・ #include<stdio.h> int main(void){ int matA[4][4],matB[4][4],matC[4][4],i,j; for(i=0;i<4;++i){ for(j=0;<4;++j){ scanf("%d",&matA[i][j]); } } for(i=0;i<4;++i){ for(j=0;<4;++j){ scanf("%d",&matB[i][j]); } } for(i=0;i<=4;++i){ for(j=0;<4;++j){ matC[i][j]=0; matC[i][j]=matA[i][j]+matB[i][j]; } } for(i=0;i<=4;++i){ for(j=0;j<4;++j){ printf("%d",matC[i][j]); } } return 0; }

  • C言語 プログラミング 行列演算

    下記のプログラムのおかしい点と解決法を教えてください。 コンパイルは通りますがうまく動きません。。 #include<stdio.h> #define MAX 500 int main(void){ int matrA[MAX][MAX],matrB[MAX][MAX],matrC[MAX][MAX],l,m,n,i,j,k; printf("lとmを入力してください:"); scanf("%d",&l); scanf("%d",&m); printf("行列Aを入力してください"); for(i=0;i<l;i++){ printf(">"); for(j=0;l<m;j++){ scanf("%d",&matrA[i][j]); } printf("\n"); } printf("nを入力してください(m = %d):",m); scanf("%d",&n); printf("行列Bを入力してください"); for(i=0;i<m;i++){ printf(">"); for(j=0;j<n;j++){ scanf("%d",&matrB[i][j]); } printf("\n"); } printf("C=\n"); for(i=0;i<l;i++){ for(j=0;j<n;j++){ for(k=0;k<m;k++){ matrC[i][j]+=matrA[i][k]*matrB[k][j]; } printf("%d",matrC[i][j]); } printf("\n"); } }

  • c言語についての質問です。

    #include<stdio.h> int main(void){ int matA[4][4],matB[4][4],matC[4][4],i,j; for(i=0;i<4;++i){ for(j=0;j<4;++j){ scanf("%d",&matA[i][j]); } } for(i=0;i<4;++i){ for(j=0;j<4;++j){ scanf("%d",&matB[i][j]); } } for(i=0;i<=4;++i){ for(j=0;j<4;++j){ matC[i][j]=0; matC[i][j]=matA[i][j]+matB[i][j]; } } for(i=0;i<=4;++i){ for(j=0;j<4;++j){ printf("%d\t",matC[i][j]); } printf("\n"); } return 0; } このプログラムをコンパイルして正しくコンパイルできました それで、もともとmatrix1and2.txtというファイルに 0 1 3 4 0 5 6 7 0 0 8 9 0 0 0 10 1 2 3 4 2 5 6 7 3 6 8 9 4 7 9 10 をつくっていて ./matSum < matrix1and2.txtで実行しても何も出てきません。泣 どうしてですか? バーチャルボックスでのLinux環境じゃ入出力のリダイレクトつかえないんですかね・・・

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

    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)); }

  • C言語 2次元配列の積について

    <演習>  4行3列の行列と3行4列の行列の積を求めるプログラムを作成    せよ。各構成要素の値はキーボードから読み込むこと。  ここに出てくる「行列」とは、数学で出てくるあの「行列」のこと でしょうか。  そうなると私が作成したプログラムは意味が違ってきます。 4回同じ事をする様になっていて1回分の計算結果だけにしたいのですが、方法が分かりません。  入門レベルの知識しかありません。ご指導の程、お願いしたいで す。 下記、プログラムを送付します。 <プログラム> #include <stdio.h> int main(void) { int i,j=0; int o,p; int a[4][3]; int b[3][4]; int m[4][4]; for (i = 0;i < 4; i++){ for (j = 0; j < 3 ; j++) { printf("a[%d][%d] = ",i,j); scanf("%d",&a[i][j]); } } printf("\n"); for (i= 0; i < 3; i++){ for (j = 0; j < 4; j++){ printf("b[%d][%d] = ",i,j); scanf("%d",&b[i][j]); } } printf("\n"); for (o = 0; o < 4; o++){ for (p = 0; p < 4; p++){ for (j = 0; j < 4; j++){ for ( i=0 ; i < 4 ;i++ ) { m[o][p] = a[i][j] * b[i][j]; printf ("a[%d][%d] = %d ," ,i, j, a[i][j]); printf ("b[%d][%d] = %d ," ,i, j, b[i][j]); printf("m[%d][%d] = %d \n",o,p,m[o][p]); } } } } return 0; }    

  • C言語を用いた45×45の逆行列の表示について・・・・。。

    次のプログラムを動かすと逆行列を求めることができます。 10×10の計算までは、スムーズに計算する事ができたのですが、 私が知りたい45×45の行列の計算になるとなぜかうまくいきません。 そこでみなさんにお聞きしたいのは、計算がうまくいかない理由がプログラムにあるのか、単にPCの限界なのか、それ以外なのか。みなさんからアドバイスをいただけないでしょうか? ※下のプログラム、見づらくてすいません。 #include <stdio.h> #define N 10 /* 元の数 */ #define N2 2*N /* プロトタイプ宣言 */ void Print(int k); /* 大域変数 */ double a[N][N2]= {/* 行列 Aおよび単位行列 */ { ここに45×45の正則行列&45×45の単位行列を入れます・・・。。 }; int main(void) { double d; int i,j,k; for (k=0;k<=N-1;k++) { Print(k); for(i=0;i<=N-1;i++) { if(i!=k) { d=a[i][k]/a[k][k]; for (j=k+1;j<=N2-1;j++) a[i][j]=a[i][j]-a[k][j]*d; a[i][k] = 0.0; } } d=a[k][k]; for (j=k;j<=N2-1;j++) a[k][j]=a[k][j]/d; } Print(N); } void Print(int k) { int i,j; printf("\n ステップ %d \n",k); /* 小見出し */ for(i=0;i<=N-1;i++) { /* 第i行を印刷 */ for(j=0;j<=N-1;j++) printf("%6.4f,",a[i][j]); printf(" : "); for(j=N;j<=N2-1;j++) printf("%6.4f,",a[i][j]); printf("\n"); } }

  • c言語 行列のn階乗のプログラム

      1 2 -1 D= 3 0 -2   -1 1 2 の3次正方行列のn乗を計算するプログラムを作成しています。 いろいろと試してみましたがうまくいきません。 どなたか教えていただけるとうれしいです。 よろしくおねがいします。 #include <stdio.h> int main(void) { int a[3][3]={ {-1,2,-1},{3,0,-2},{-1,1,2} }; int b[3][3]={ {-1,2,-1},{3,0,-2},{-1,1,2} }; int s[3][3]; int m,n; int i,j,k; printf("[A]^n;n = ");scanf("%d",&n); for (m=2;m <= n;m++){ for (i=0;i<3;i++){ for (j=0;j<3;j++){ s[i][j] = 0; for(k=0;k<3;k++){ s[i][j] =s[i][j] + a[i][k] * b[k][j]; } } } for(i=0;i<3;i++){ for(j=0;j<3;j++){ b[i][j]=s[i][j]; } } printf("%3d",s[i][j]); putchar('\n'); } return (0); }

専門家に質問してみよう