【gyoretsu.cのソースコード】
/*
* 行列の積の計算と表示をするプログラム
* gyoretsu.c
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h> /* strlen() */
#include <ctype.h> /* isdigit() */
#include <time.h> /* time() */
#define BUF_SIZE 256
/*
* 自作のbool型の定義
*/
typedef enum {
false, /* 0 */
true /* 1 */
} bool;
/*
* ユーザー定義関数の関数原型宣言
*/
void print_title(void);
void input(void);
bool is_valid_number(char buf[]);
void subst_rand(void);
void calc(void);
void print_result(void);
bool retry(void);
/*
* グローバル変数
*/
int I, J, K, i, j, k;
int a[5][5], b[5][5], c[5][5];
/*
* メイン関数
*/
int main(void)
{
/* 乱数の種の発生 */
srand((unsigned int)time(NULL));
while (1) {
/* 標題・説明の表示 */
print_title();
/* 行数および列数の入力 */
input();
/* 擬似乱数の代入 */
subst_rand();
/* 計算 */
calc();
/* 結果の表示 */
print_result();
/* 操作を続けるかどうかの選択 */
if (!retry())
break;
}
return EXIT_SUCCESS;
}
/*
* 標題および説明を表示する関数
*/
void print_title(void)
{
printf("【行列の積の計算と表示】\n\n");
printf("行列の積\n");
printf("A(I行K列)×B(K行J列) = C(I行J列)\n");
printf("の計算をします。\n");
printf("(ただし、I、J、Kは1~5の整数)\n\n");
}
/*
* 行数および列数を入力する関数
* is_valid_number()関数を使用する。
*/
void input(void)
{
char buf[BUF_SIZE], zz;
printf("I、J、Kを順に入力してください。\n");
printf("(ただし、I、J、Kは1~5の整数)\n\n");
while (1) {
printf("エンターキーを押してください・・・");
fgets(buf, sizeof buf, stdin);
sscanf(buf, "%c", &zz);
if (zz != '\n')
continue;
else
break;
}
printf("\n");
while (1) {
printf("I = ? ");
fgets(buf, sizeof buf, stdin);
buf[strlen(buf) - 1] = '\0';
sscanf(buf, "%d%c", &I, &zz);
if (!is_valid_number(buf)) {
printf("半角整数値を入力してください\n");
continue;
} else if ((I < 1) || (I > 5)) {
printf("1から5の整数を入力してください: ");
continue;
} else
break;
}
while (1) {
printf("J = ? ");
fgets(buf, sizeof buf, stdin);
buf[strlen(buf) - 1] = '\0';
sscanf(buf, "%d%c", &J, &zz);
if (!is_valid_number(buf)) {
printf("半角整数値を入力してください\n");
continue;
} else if ((J < 1) || (J > 5)) {
printf("1から5の整数を入力してください: ");
continue;
} else
break;
}
while (1) {
printf("K = ? ");
fgets(buf, sizeof buf, stdin);
buf[strlen(buf) - 1] = '\0';
sscanf(buf, "%d%c", &K, &zz);
if (!is_valid_number(buf)) {
printf("半角整数値を入力してください\n");
continue;
} else if ((K < 1) || (K > 5)) {
printf("1から5の整数を入力してください: ");
continue;
} else
break;
}
}
/*
* 文字列が正しい形式の整数値かどうかを判定する関数
*/
bool is_valid_number(char buf[])
{
int i = 0;
/* 最初は符号(省略可) */
if (buf[i] == '+' || buf[i] == '-')
i++;
/* 次に数字(省略不可) */
if (!isdigit(buf[i]))
return 0;
i++;
/* 次に数字列(省略可) */
while (isdigit(buf[i]))
i++;
return buf[i] == '\0';
}
/*
* 行列の成分に擬似乱数を代入する関数
*/
void subst_rand(void)
{
char buf[BUF_SIZE], zz;
printf("行列A、Bの成分に、擬似乱数を自動で代入します。\n");
while (1) {
printf("エンターキーを押してください・・・");
fgets(buf, sizeof buf, stdin);
sscanf(buf, "%c", &zz);
if (zz != '\n')
continue;
else
break;
}
printf("\n");
printf("行列A(%d行%d列)", I, K);
for (i = 0; i < I; i++) {
printf("\n\t");
for (k = 0; k < K; k++) {
a[i][k] = rand() % 20 - 10;
printf("%4d", a[i][k]);
}
}
printf("\n");
printf("行列B(%d行%d列)", K, J);
for (k = 0; k < K; k++) {
printf("\n\t");
for (j = 0; j < J; j++) {
b[k][j] = rand() % 20 - 10;
printf("%4d", b[k][j]);
}
}
printf("\n");
}
/*
* 計算をする関数
*/
void calc(void)
{
char buf[BUF_SIZE], zz;
printf("行列の積 A×B = C を計算します。\n");
while (1) {
printf("エンターキーを押してください・・・");
fgets(buf, sizeof buf, stdin);
sscanf(buf, "%c", &zz);
if (zz != '\n')
continue;
else
break;
}
printf("\n");
for (i = 0; i < I; i++)
for (j = 0; j < J; j++) {
c[i][j] = 0;
for (k = 0; k < K; k++)
c[i][j] += a[i][k] * b[k][j];
}
}
/*
* 計算結果を表示する関数
*/
void print_result(void)
{
printf("\n");
printf("行列C(%d行%d列)", I, J);
for (i = 0; i < I; i++) {
printf("\n\t");
for (j = 0; j < J; j++)
printf("%5d", c[i][j]);
}
printf("\n");
}
/*
* 操作を続けるかどうかを選択する関数
* true: 繰り返す、false: 終了する。
*/
bool retry(void)
{
bool ret;
char buf[BUF_SIZE], ch, zz;
while (1) {
printf("\n続けますか?(y/n) ");
fgets(buf, sizeof buf, stdin);
sscanf(buf, "%c%c", &ch, &zz);
if (((ch == 'y') || (ch == 'Y')) && (zz == '\n')) {
printf("\n+++++\n\n");
ret = true;
break;
} else if (((ch == 'n') || (ch == 'N')) && (zz == '\n')) {
ret = false;
break;
}
printf("無効な入力です。\n");
printf("yまたはnを入力してください。\n");
}
return ret;
}
C:\Users\skonishi\Documents>gyoretsu
【行列の積の計算と表示】
行列の積
A(I行K列)×B(K行J列) = C(I行J列)
の計算をします。
(ただし、I、J、Kは1~5の整数)
I、J、Kを順に入力してください。
(ただし、I、J、Kは1~5の整数)
エンターキーを押してください・・・[エンター]キー
I = ? 3
J = ? 4
K = ? 5
行列A、Bの成分に、擬似乱数を自動で代入します。
エンターキーを押してください・・・[エンター]キー
行列A(3行5列)
-4 7 5 0 2
1 9 -6 -9 2
8 1 -10 -4 8
行列B(5行4列)
1 -9 -10 -1
-5 -10 4 7
3 3 -7 -4
-1 1 3 7
9 9 -2 8
行列の積 A×B = C を計算します。
エンターキーを押してください・・・[エンター]キー
行列C(3行4列)
-6 -1 29 49
-35 -108 37 39
49 -44 -34 75
続けますか?(y/n) y
+++++
【行列の積の計算と表示】
行列の積
A(I行K列)×B(K行J列) = C(I行J列)
の計算をします。
(ただし、I、J、Kは1~5の整数)
I、J、Kを順に入力してください。
(ただし、I、J、Kは1~5の整数)
エンターキーを押してください・・・[エンター]キー
I = ? 1
J = ? 1
K = ? 5
行列A、Bの成分に、擬似乱数を自動で代入します。
エンターキーを押してください・・・[エンター]キー
行列A(1行5列)
-6 1 -10 -2 -3
行列B(5行1列)
-4
3
-3
6
1
行列の積 A×B = C を計算します。
エンターキーを押してください・・・[エンター]キー
行列C(1行1列)
42
続けますか?(y/n) y
+++++
【行列の積の計算と表示】
行列の積
A(I行K列)×B(K行J列) = C(I行J列)
の計算をします。
(ただし、I、J、Kは1~5の整数)
I、J、Kを順に入力してください。
(ただし、I、J、Kは1~5の整数)
エンターキーを押してください・・・[エンター]キー
I = ? 5
J = ? 5
K = ? 1
行列A、Bの成分に、擬似乱数を自動で代入します。
エンターキーを押してください・・・[エンター]キー
行列A(5行1列)
2
-4
7
8
-10
行列B(1行5列)
4 -10 7 -2 -3
行列の積 A×B = C を計算します。
エンターキーを押してください・・・[エンター]キー
行列C(5行5列)
8 -20 14 -4 -6
-16 40 -28 8 12
28 -70 49 -14 -21
32 -80 56 -16 -24
-40 100 -70 20 30
続けますか?(y/n) n
戻る