ページ 11

C言語、行列の積と行列式を求めるプログラムについての質問です。

Posted: 2011年2月10日(木) 11:04
by 新野
こんにちは、新野と申します。
プログラミングに関しては初心者です。
ここの皆様の力をお借りしたく、書き込みさせていただきました。

今、行列の積とその行列式を出すプログラムを作っています。
以下のコードで一応動作確認しました。(visual basic2008?を使っています)

コード:

#include <stdio.h>
void matrix(const int ma[3][3],const int mb[3][3],int mc[3][3])
{
int i,j,k;
for(i = 0; i < 3; i++)
for(j = 0;j < 3;j++)
for(k=0;k<3;k++)
mc[i][j]+=ma[i][k]*mb[k][j];
}
int main(void)
{
int i,j;
int ma[3][3] ={{1,3,4},{7,3,2},{9,11,2}};
int mb[3][3] ={{4,6,7},{6,7,3},{8,2,3}};
int mc[3][3] ={0};
matrix(ma,mb,mc);
for(i = 0;i < 3; i++)
{
for(j = 0;j < 3;j++)
printf("%4d",mc[i][j]);
printf("\n");
}
printf("Cの行列式は");
int det=0.0;
det=mc[0][0]*mc[1][1]*mc[2][2];
det+=mc[1][0]*mc[2][1]*mc[0][2];
det+=mc[2][0]*mc[0][1]*mc[1][2];
det-=mc[2][0]*mc[1][1]*mc[0][2];
det-=mc[1][0]*mc[0][1]*mc[2][2];
det-=mc[0][0]*mc[2][1]*mc[1][2];
printf("%4d",det); 
printf("です。");
printf("\n\n");
return(0);
}
参考書を片手に書いたものです。
あまり詳しい仕組みまでは理解できないまでも、結果の数値はあっているようです。
そこで質問なのですが・・・。
今、行列の積については、関数matrixで表しています。
行列式も関数detaminantで表したいのですが、どのようにすればいいでしょうか?
また、上のプログラムについても、「ここはおかしい」「ここはこうしたほうがよい」などあればご教授願います。

Re: C言語、行列の積と行列式を求めるプログラムについての質問です。

Posted: 2011年2月10日(木) 12:05
by maru
新野 さんが書きました:行列式も関数detaminantで表したいのですが、どのようにすればいいでしょうか?
新野 さんが書きました:

コード:

int det=0.0;
det=mc[0][0]*mc[1][1]*mc[2][2];
det+=mc[1][0]*mc[2][1]*mc[0][2];
det+=mc[2][0]*mc[0][1]*mc[1][2];
det-=mc[2][0]*mc[1][1]*mc[0][2];
det-=mc[1][0]*mc[0][1]*mc[2][2];
det-=mc[0][0]*mc[2][1]*mc[1][2];
ここまで出来ているのですから、これを関数化すればよいだけではないのですか?何かそれでは不満があるのでしょうか?
ただし、
int det=0.0;
ではコンパイル時にエラーまたは警告が出るでしょうね。

コード:

int	detaminant(int mc[3][3])
{
	int det = mc[0][0]*mc[1][1]*mc[2][2];
	det += mc[1][0]*mc[2][1]*mc[0][2];
	det += mc[2][0]*mc[0][1]*mc[1][2];
	det -= mc[2][0]*mc[1][1]*mc[0][2];
	det -= mc[1][0]*mc[0][1]*mc[2][2];
	det -= mc[0][0]*mc[2][1]*mc[1][2];
	return det;
}

Re: C言語、行列の積と行列式を求めるプログラムについての質問です。

Posted: 2011年2月10日(木) 12:16
by softya(ソフト屋)
新野さん、はじめまして。
visual basic2008では無く、VisualStudio2008に含まれるVisualC++2008が正しいです。
VisualBasicはC言語とは別の言語です。

それと今後のためにインデント(字下げ)をする癖を付けられた方が良いと思います。
VisualStudio2008には自動で字下げする機能もあります。
編集→詳細→選択範囲のフォーマットで字下げ出来ます。
直前にCTRL+Aでソース全体を選択しておいてください。

maruさんが回答を書かれていますが、detaminant内をループで記述したいとか行列が3x3固定なのを可変にしたいとかの機能追加も検討されると面白いと思いますよ。

Re: C言語、行列の積と行列式を求めるプログラムについての質問です。

Posted: 2011年2月10日(木) 12:28
by 新野
返信ありがとうございます。
言葉足らずで申し訳ありません。
関数を作ること自体はわかるのですが、関数の構成自体がいまいちわかっておらず、
関数を作った後、それの呼び出し方がいまいちわかっていないのです。
おっしゃったように関数化して、そのあとメイン関数の中でdetaminantを呼び出すとき
detaminant()←この中には何を入れてあげれば良いのか、あとそれをどの行に持っていけばよいのか・・・。
ご指導願えませんでしょうか。
初歩の質問で申し訳ありません(泣)

Re: C言語、行列の積と行列式を求めるプログラムについての質問です。

Posted: 2011年2月10日(木) 12:32
by 新野
ソフト屋さん、ありがとうございます。
返信のタイミングがずれてしまい申し訳ありません。
アドバイスありがとうございます、勉強になりました。
visualstdioの件も確かにそうみたいでした。勉強不足で申し訳ありません。
とりあえずdetaminantの関数化ができ次第、その先についても検討していきたいと思います。
ありがとうございました^^

Re: C言語、行列の積と行列式を求めるプログラムについての質問です。

Posted: 2011年2月10日(木) 12:35
by softya(ソフト屋)
関数の引数・戻り値・配列については、大体どのようなC言語の入門書でも書かれている思いますが、今現在読まれている書籍は何をお使いでしょうか?

Re: C言語、行列の積と行列式を求めるプログラムについての質問です。

Posted: 2011年2月10日(木) 13:03
by 新野
ソフト屋さん
学生のためのCを使っています。
基本はわかるのですが、それらを組み合わせた応用になるとさっぱりで・・・。
いろいろ試してはいるのですが、うまくコンパイルできないでいます。

Re: C言語、行列の積と行列式を求めるプログラムについての質問です。

Posted: 2011年2月10日(木) 13:11
by softya(ソフト屋)
ひとつの本だけだと分かりづらい事もありかと思います。
サイトをご紹介します(ただ、サイトですので間違いも多いかと思います)。
それぞれ書かれていること読み比べることで見えてくることあると思いますので読んでみてください。

「苦しんで覚えるC言語」
http://9cguide.appspot.com/
「C言語入門」
http://www5c.biglobe.ne.jp/~ecb/c/c00.html
「C言語編 トップページ」
http://www.geocities.jp/ky_webid/c/index.html

Re: C言語、行列の積と行列式を求めるプログラムについての質問です。

Posted: 2011年2月10日(木) 13:23
by 新野
ここで言ってくださったことを踏まえてもういちどよく考えて、結局このようなプログラムにしました。
とりあえず自分の中では解決かな、と思っています。

コード:

#include <stdio.h>

void matrix(const int ma[3][3],const int mb[3][3],int mc[3][3])
{

int i,j,k;
for(i = 0; i < 3; i++)
for(j = 0;j < 3;j++)
for(k=0;k<3;k++)
mc[i][j]+=ma[i][k]*mb[k][j];
}
int detaminant(int mc[3][3])
{
    int det;
    det	= mc[0][0]*mc[1][1]*mc[2][2];
    det += mc[1][0]*mc[2][1]*mc[0][2];
    det += mc[2][0]*mc[0][1]*mc[1][2];
    det -= mc[2][0]*mc[1][1]*mc[0][2];
    det -= mc[1][0]*mc[0][1]*mc[2][2];
    det -= mc[0][0]*mc[2][1]*mc[1][2];
    return det;
}

int main(void)
{
int i,j,d;
int ma[3][3] ={{1,3,4},{7,3,2},{9,11,2}};
int mb[3][3] ={{4,6,7},{6,7,3},{8,2,3}};
int mc[3][3] ={0};
matrix(ma,mb,mc);
printf("C=A*B\n");
for(i = 0;i < 3; i++)
{
for(j = 0;j < 3;j++)
printf("%4d",mc[i][j]);
printf("\n");
}
d=detaminant(mc);
printf("Cの行列式は");

printf("%4d",d); 
printf("です。");
printf("\n\n");
return(0);
}
学校の課題でしたので、とりあえず教科書は今回の分だけでなんとかしました。
これから先も勉強していきたいので、指定してくださったサイトも参考にさせていただきます。
ありがとうございました!