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; }
改善案ありがうございます!
返信削除参考にしてできるかぎり改善しようと思います!