1. グローバル変数が多数の関数内で参照 & 書き換えがされていて、修正が容易でないこと。
2. 同じ変数について、ifでの分岐があちこちに散在していてバグの元となること。
3. 「3.14」の精度が足りない場合がある。それ以前にプログラム中に出てくる定数はマジックナンバーと呼ばれ、修正が大変になるので事前に定義しておく。
#include <stdio.h>
#define _USE_MATH_DEFINES
#include <math.h>
double chouhoukei(double* ref_m, double ro);
double nagaibou(double* ref_m, double ro);
double enban(double* ref_m, double ro);
double enchuu(double* ref_m, double ro);
double entou(double* ref_m, double ro);
double kyuu(double* ref_m, double ro);
double kyuukaku(double* ref_m, double ro);
static const double g_ro[3] = { 2.7 / 1000000, 7.9 / 1000000, 1.19 / 1000000 };
static const double (*f[7])(double*, double) = { chouhoukei, nagaibou, enban, enchuu, entou, kyuu, kyuukaku };
int main(void) {
int i;
float t0 = 0;
printf("任意の軸(機力の教科書p251の図参照)まわりの慣性モーメントJ[kgcm^2]\n");
for(i = 1; ; i++) {
// 使う変数の領域を考えて極量スコープを小さく
int u, n;
double e, m, ro, t;
printf("部材を番号で選んでください\n0.アルミ,1.ステンレス,2.アクリル,3.その他(密度既知)\n4.その他(質量既知),5.終了\n");
scanf("%d", &u);
// 密度既知の場合
if(u >= 0 && u <= 2) {
ro = g_ro[u];
}
else if(u == 3) {
ro = 0;
printf("密度[kg/m^3]を入力してください\n");
scanf("%lf", ro);
ro /= 1000000000;
}
else if(u == 5) {
break;
}
printf("部品%dの形を番号で選んでください.\n1.長方形板,2.長い棒,3.薄い円盤,4.円柱,5.円筒形\n6.球,7.球殻,8その他(慣性モーメント既知)\n", i);
scanf("%d", &n);
// 質量既知の場合
if(u == 4) {
printf("質量[g]を入力してください\n");
scanf("%lf", &m);
m /= 1000;
ro = 0;
}
else {
m = 0;
}
// 慣性モーメントが既知の場合
if(n == 8) {
printf("\n部品%dの慣性モーメント[kgmm^2]を入力してください\n\n", i);
scanf("%lf", &t);
}
// 想定外の値が入力されたらエラーを表示
else if(n < 0 || n > 8) {
// printf("nは1から8の範囲で入力して下さい\n");
continue;
}
// elseを使う場面
else {
printf("重心の回転軸からの距離[mm]を入力してください\n");
scanf("%lf", &e);
// 同じ処理はまとめる
t = (*f[n - 1])(&m, ro) + e * e * m;
printf("\n部品%dの質量=%lf[kg]\n", i, m);
printf("部品%dのJ=%lf[kgcm^2]\n\n", i, t / 100);
}
t0 += t / 100;
}
printf("\n全体の慣性モーメント\nJ=%lf[kgcm^2]", t0);
return 0; // 正常の場合はmain関数は0(EXIT_SUCCESS)を返す
}
double chouhoukei(double* ref_m, double ro) {
int p;
double a, b, tt, m;
printf("回転軸を選んでください\n0.x 1.y 2.z\n");
scanf("%d", &p);
printf("横の長さ[mm]を入力してください\n");
scanf("%lf", &b);
printf("縦の長さ[mm]を入力してくだいさい\n");
scanf("%lf", &a);
m = *ref_m;
if(m == 0) {
printf("厚さ[mm]を入力してください\n");
scanf("%lf", &tt);
m = ro * (a * b * tt);
*ref_m = m;
}
switch(p) {
case 0:
return a * a * m / 12;
case 1:
return b * b * m / 12;
case 2:
return ((a * a + b * b) * m) / 12;
}
return 0;
}
double nagaibou(double* ref_m, double ro) {
double l, tt, m;
printf("長さ[mm]を入力してください\n");
scanf("%lf", &l);
m = *ref_m;
if(m == 0) {
printf("直径[mm]を入力してください\n");
scanf("%lf", &tt);
m = ro * (M_PI * tt * tt / 4) * l;
*ref_m = m;
}
return m * l * l / 12;
}
double enban(double* ref_m, double ro) {
double r, tt, m;
int p;
printf("回転軸を選んでください\n0.x 1.y 2.z\n");
scanf("%d", &p);
printf("半径[mm]を入力してください\n");
scanf("%lf", &r);
m = *ref_m;
if(m == 0) {
printf("厚さ[mm]を入力してください\n");
scanf("%lf", &tt);
*ref_m = ro * M_PI * r * r * tt;
m = *ref_m;
}
switch(p) {
case 0:
return r * r * m / 4;
case 1:
return r * r * m / 4;
case 2:
return r * r * m / 2;
}
return 0;
}
double enchuu(double* ref_m, double ro) {
int p;
double r, l, m;
printf("回転軸を選んでください\n0.x 1.y 2.z\n");
scanf("%d", &p);
printf("半径[mm]を入力してください\n");
scanf("%lf", &r);
printf("長さ[mm]を入力してくだいさい\n");
scanf("%lf", &l);
m = *ref_m;
if(m == 0) {
m = ro * M_PI * r * r * l;
*ref_m = m;
}
switch(p) {
case 0:
return (r * r / 2 + l * l / 12) * m;
case 1:
return (r * r / 2 + l * l / 12) * m;
case 2:
return r * r * m / 2;
}
return 0;
}
double entou(double* ref_m, double ro) {
int p;
double r, l, tt, m;
printf("回転軸を選んでください\n0.x 1.y 2.z\n");
scanf("%d", &p);
printf("半径[mm]を入力してください\n");
scanf("%lf", &r);
// これ忘れているんじゃないか?
printf("長さ[mm]を入力してくだいさい\n");
scanf("%lf", &l);
// ここまで
m = *ref_m;
if(m == 0) {
printf("筒の厚さ[mm]を入力してください\n");
scanf("%lf", &tt);
m = ro * M_PI * r * r * l - M_PI * (r - tt) * (r - tt) * l;
*ref_m = m;
}
switch(p) {
case 0:
return (r * r / 2 + l * l / 12) * m;
case 1:
return (r * r / 2 + l * l / 12) * m;
case 2:
return r * r * m;
}
return 0;
}
double kyuu(double* ref_m, double ro) {
double r, m;
printf("半径[mm]を入力してください\n");
scanf("%lf", &r);
m = *ref_m;
if(m == 0) {
m = ro * 4 * M_PI * r * r * r / 3;
*ref_m = m;
}
return 2 * m * r * r / 5;
}
double kyuukaku(double* ref_m, double ro) {
double r, tt, m;
printf("半径[mm]を入力してください\n");
scanf("%lf", &r);
m = *ref_m;
if(m == 0) {
printf("核の厚さ[mm]を入力してください\n");
scanf("%lf", &tt);
m = ro * 4 * M_PI * r * r * r / 3 - 4 * M_PI * (r - tt) * (r - tt) * (r - tt) / 3;
*ref_m = m;
}
return 2 * r * r * m / 3;
}
改善案ありがうございます!
返信削除参考にしてできるかぎり改善しようと思います!