【gyoretsu.cのソースコード】
/*
* 行列の積の計算をするプログラム
* gyoretsu.c
*/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h> /* strcspn */
#include <ctype.h> /* isdigit */
#define BUF_SIZE 256
/*
* 自作のbool型の定義
*/
typedef enum {
false,
true
} bool;
/*
* ユーザー定義関数の関数原型宣言
*/
void initialize(void);
void print_title(void);
void input_enter(void);
void input(void);
bool is_valid_integer(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)
{
/* 初期化 */
initialize();
while (1) {
/* 標題・説明の表示 */
print_title();
/* 行数および列数の入力 */
input();
/* 擬似乱数の代入 */
subst_rand();
/* 計算 */
calc();
/* 結果の表示 */
print_result();
/* 操作を続けるかどうかの選択 */
if (!retry())
return EXIT_SUCCESS;
}
}
/*
* 初期化を行う関数
*/
void initialize(void)
{
/* 乱数系列の設定 */
srand((unsigned int)time(NULL));
}
/*
* 標題および説明を表示する関数
* input_enter関数を使用する。
*/
void print_title(void)
{
printf("【行列の積の計算と表示】\n\n行列の積\n"
"A(I行J列) × B(J行K列) = C(I行K列)\nの計算をします。\n"
"(ただし、I、J、Kは1~5の整数)\n\n");
input_enter();
}
/*
* エンターキーの入力を受け付ける関数
*/
void input_enter(void)
{
char buf[BUF_SIZE], zz;
while (1) {
printf("エンターキーを押してください・・・");
fgets(buf, sizeof buf, stdin);
sscanf(buf, "%c", &zz);
if (zz != '\n')
continue;
else
break;
}
printf("\n");
}
/*
* 行数および列数を入力する関数
* input_enter関数およびis_valid_integer関数を使用する。
*/
void input(void)
{
char buf[BUF_SIZE], zz;
printf("I、J、Kを順に入力してください。\n"
"(ただし、I、J、Kは1~5の整数)\n\n");
input_enter();
while (1) {
printf("I = ? ");
fgets(buf, sizeof buf, stdin);
buf[strcspn(buf, "\n")] = '\0';
sscanf(buf, "%d%c", &I, &zz);
if (!is_valid_integer(buf)) {
printf("半角整数値を入力してください。\n");
continue;
} else if ((I < 1) || (5 < I)) {
printf("1から5の整数を入力してください。\n");
continue;
} else
break;
}
while (1) {
printf("J = ? ");
fgets(buf, sizeof buf, stdin);
buf[strcspn(buf, "\n")] = '\0';
sscanf(buf, "%d%c", &J, &zz);
if (!is_valid_integer(buf)) {
printf("半角整数値を入力してください。\n");
continue;
} else if ((J < 1) || (5 < J)) {
printf("1から5の整数を入力してください。\n");
continue;
} else
break;
}
while (1) {
printf("K = ? ");
fgets(buf, sizeof buf, stdin);
buf[strcspn(buf, "\n")] = '\0';
sscanf(buf, "%d%c", &K, &zz);
if (!is_valid_integer(buf)) {
printf("半角整数値を入力してください。\n");
continue;
} else if ((K < 1) || (5 < K)) {
printf("1から5の整数を入力してください。\n");
continue;
} else
break;
}
}
/*
* 文字列が正しい形式の整数値かどうかを判定する関数
* true: 正しい形式である、false: 無効な形式である。
*/
bool is_valid_integer(char buf[])
{
int i = 0;
/* 空文字列ならば偽を返す */
if (buf[0] == '\0')
return false;
/* 最初は符号(省略可) */
if (buf[i] == '+' || buf[i] == '-')
i++;
/* 次に数字(省略不可) */
if (!isdigit((unsigned char)buf[i]))
return false;
i++;
/* 次に数字列(省略可) */
while (isdigit((unsigned char)buf[i]))
i++;
/* 他に余計な文字がなければ真、あれば偽を返す */
return buf[i] == '\0';
}
/*
* 行列の成分に擬似乱数を代入する関数
* input_enter関数を使用する。
*/
void subst_rand(void)
{
char buf[BUF_SIZE], zz;
printf("\n行列A、Bの成分に、擬似乱数を自動で代入します。\n");
input_enter();
/* 代入および表示 */
printf("行列A(%d行%d列)", I, J);
for (i = 0; i < I; i++) {
printf("\n\t");
for (j = 0; j < J; j++) {
a[i][j] = rand() % 20 - 10;
printf("%4d", a[i][j]);
}
}
printf("\n");
printf("行列B(%d行%d列)", J, K);
for (j = 0; j < J; j++) {
printf("\n\t");
for (k = 0; k < K; k++) {
b[j][k] = rand() % 20 - 10;
printf("%4d", b[j][k]);
}
}
printf("\n");
}
/*
* 計算をする関数
* input_enter関数を使用する。
*/
void calc(void)
{
char buf[BUF_SIZE], zz;
printf("\n行列の積 A × B = C を計算します。\n");
input_enter();
/* 計算 */
for (i = 0; i < I; i++)
for (k = 0; k < K; k++) {
c[i][k] = 0;
for (j = 0; j < J; j++)
c[i][k] += a[i][j] * b[j][k];
}
}
/*
* 計算結果を表示する関数
*/
void print_result(void)
{
printf("行列C(%d行%d列)", I, K);
for (i = 0; i < I; i++) {
printf("\n\t");
for (k = 0; k < K; k++)
printf("%5d", c[i][k]);
}
printf("\n");
}
/*
* 操作を繰り返すかどうかを選択する関数
* true: 繰り返す、false: 終了する。
*/
bool retry(void)
{
bool flag;
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");
flag = true;
break;
} else if ((ch == 'n' || ch == 'N') && zz == '\n') {
flag = false;
break;
}
printf("無効な入力です。\nyまたはnを入力してください。\n");
}
return flag;
}
C:\Users\skonishi\Documents>gyoretsu
【行列の積の計算と表示】
行列の積
A(I行J列) × B(J行K列) = C(I行K列)
の計算をします。
(ただし、I、J、Kは1~5の整数)
エンターキーを押してください・・・[エンター]キー
I、J、Kを順に入力してください。
(ただし、I、J、Kは1~5の整数)
エンターキーを押してください・・・[エンター]キー
I = ? 5
J = ? 3
K = ? 4
行列A、Bの成分に、擬似乱数を自動で代入します。
エンターキーを押してください・・・[エンター]キー
行列A(5行3列)
-5 -9 -8
6 9 6
8 -7 0
2 5 1
6 -10 9
行列B(3行4列)
-10 8 -10 -7
-8 7 0 -7
-8 -8 8 -8
行列の積 A × B = C を計算します。
エンターキーを押してください・・・[エンター]キー
行列C(5行4列)
186 -39 -14 162
-180 63 -12 -153
-24 15 -80 -7
-68 43 -12 -57
-52 -94 12 -44
繰り返しますか?(y/n) y
+++++
【行列の積の計算と表示】
行列の積
A(I行J列) × B(J行K列) = C(I行K列)
の計算をします。
(ただし、I、J、Kは1~5の整数)
エンターキーを押してください・・・[エンター]キー
I、J、Kを順に入力してください。
(ただし、I、J、Kは1~5の整数)
エンターキーを押してください・・・[エンター]キー
I = ? 1
J = ? 5
K = ? 1
行列A、Bの成分に、擬似乱数を自動で代入します。
エンターキーを押してください・・・[エンター]キー
行列A(1行5列)
-8 8 -1 -6 0
行列B(5行1列)
-9
-9
-8
-2
8
行列の積 A × B = C を計算します。
エンターキーを押してください・・・[エンター]キー
行列C(1行1列)
20
繰り返しますか?(y/n) y
+++++
【行列の積の計算と表示】
行列の積
A(I行J列) × B(J行K列) = C(I行K列)
の計算をします。
(ただし、I、J、Kは1~5の整数)
エンターキーを押してください・・・[エンター]キー
I、J、Kを順に入力してください。
(ただし、I、J、Kは1~5の整数)
エンターキーを押してください・・・[エンター]キー
I = ? 5
J = ? 1
K = ? 5
行列A、Bの成分に、擬似乱数を自動で代入します。
エンターキーを押してください・・・[エンター]キー
行列A(5行1列)
-3
0
-7
-2
2
行列B(1行5列)
-5 -10 -2 6 6
行列の積 A × B = C を計算します。
エンターキーを押してください・・・[エンター]キー
行列C(5行5列)
15 30 6 -18 -18
0 0 0 0 0
35 70 14 -42 -42
10 20 4 -12 -12
-10 -20 -4 12 12
繰り返しますか?(y/n) n
戻る
©2017 KONISHI, Shoichiro.