プログラミング実習II (2026) 課題

[E5] 第5章 関数(2)

「グローバル変数」は便利な面もありますが,プログラミングのミスを招きやすいため注意が必要です.本課題では引数・戻り値の概念を理解するため,グローバル変数を用いずに解答してください.
(E5_1)

整数 m の階乗を求めるプログラムを作成せよ.正しい数値が表示されない場合はその理由を考察せよ.

表示例
           fact   lfact
-----------------------------
   1!  =     1      1
   2!  =     2      2
   3!  =     6      6
   4!  =    24     24
   5!  =   120    120
               :
  30!  =    ...
#include <stdio.h>

long long lfact( int );

int main( void ){
	int i;

	printf("%d! = %lld \n", i, lfact( i ) );

	return 0;
}

long long lfact( int n ){
    int i;
    long long fact;

    return fact;
}
(E5_2)

キーボードから 12 以下の整数 n と,1.0 未満の正の実数 p を受け取る. 次に,当たり確率 p のくじを n 回引くとき,当たりが i 回出る確率 nCi * pi * (1-p)(n-i) を計算して i = 0, 1, 2, ..., n に対して表示せよ.

    int n;
    double p;
    scanf("%d", &n);
    scanf("%lf", &p);  // パーセント エル エフ
 表示例( n = 10, p = 0.5 )
  i = 0, 0.000977
  i = 1, 0.009766
  i = 2, 0.043945
  i = 3, 0.117188
  i = 4, 0.205078
  i = 5, 0.246094
  i = 6, 0.205078
  i = 7, 0.117188
  i = 8, 0.043945
  i = 9, 0.009766
  i = 10, 0.000977
(E5_3)

ニュートン法による平方根計算 [リスト 5.11] を参考に,3 乗根を計算する関数 double mycbrt( double x ) を追加せよ.

[リスト 5.11] の mysqrt は, ニュートン法により という数列が x の平方根に収束することを利用して計算を行っている.
      x             r         r*r*r
    1.0  1.0000000000  1.0000000000
    2.0  1.2599210499  2.0000000000
    3.0  1.4422495703  3.0000000000
    4.0  1.5874010520  4.0000000000
    5.0  1.7099759467  5.0000000000
    6.0  1.8171205928  6.0000000000
    7.0  1.9129311828  7.0000000000
    8.0  2.0000000000  8.0000000000
    9.0  2.0800838231  9.0000000000
   10.0  2.1544346900 10.0000000000
(E5_4)

4 個の整数の最大値を求めて表示するプログラムを作成する.まず,2個の引数 a, b のうち大きい方を戻り値とする関数 int max2( int a, int b )を作成せよ.

さらに関数 max2 を用いて max4 を構成する手法(関数のネスト呼び出しという)を理解すること.

int max2( int a, int b );

int max4( int a, int b, int c, int d ){
    return max2( max2( a, b ), max2( c, d ) );
}

同様に min2, min4 も作成し,4 つの入力値の最小値を求めて表示するプログラムを追加せよ.

その上で,main 関数内で a, b, c, d として適当な整数を代入し,a, b, c, d の値とその最大値と最小値を表示する.これを 5 組の整数 a, b, c, d に対して行い,プログラムの正しさを検証すること.

a = 3, b = 9, c = 4, d = 10 : max = 10, min = 3
a =  , b =  , c =  , d =    : max =   , min = 
a =  , b =  , c =  , d =    : max =   , min = 
a =  , b =  , c =  , d =    : max =   , min = 
a =  , b =  , c =  , d =    : max =   , min = 
(E5_5)

「キックオフ C言語」 3.10節 練習問題 4(【計算式による実引数・浮動小数点の誤差】a, b を適当に定めて…)に解答せよ.作成した関数を利用し,動作が確認できるような C 言語のプログラムを作成して提出すること.

(E5_6)

以下に示すプログラムについて,解答せよ.ただし,以下の小問にある通り,このプログラムには無駄な箇所がある.

  1. main() には count_down( n ) の呼び出しが 2 回あるが,nの値は変化するか,レポートにて解答せよ.実行前の予想と実行後の結果を記して考察すること.
  2. n の定義が [A], [B], [C] の3ヶ所にあるが,無駄な定義が含まれる.いずれがこれに当たるか,理由とともにレポートで解答せよ(ただし,以下の問題の都合上,この変数をプログラムから削除しないこと).
  3. [C]int n = 3; をコメントにする(すなわち // int n = 3; とする)と, どのように動作が変化するかレポートにて解答せよ.実行前の予想と実行後の結果を記して考察すること.
  4. [B]int n を削除する(すなわち void count_down( ) とする)と, どのように動作が変化するか.実行前の予想と実行後の結果を記して考察すること.
  5. [B]int nvoid に置き換える(すなわち void count_down( void ) とする)と,どうなるか.実行前の予想と実行後の結果を記して考察すること.
    必要に応じて,エラーを解消するように main() 側の呼び出しを修正せよ.

#include <stdio.h>

int n = 10;     // [A]

/* n回のカウントダウンを行う */
void count_down( int n ) {      // [B]
	while (n >= 0) {
		printf("n=%d\n", n);
		n--;
	}
	printf("fire!!\n\n");
}

int main( void ) {
	int n = 3;      // [C]

	count_down(5);
	count_down(n);
	count_down(n);

	return 0;
}
(E5_7*)

まず練習として「キックオフ C言語」 6.5節 練習問題 7(【数列の和】以下の数列…)に解答せよ.適切な関数を作成して利用することが望ましい(以下の問題が難しい場合は,ここまでで作成したプログラムを提出してもよい).

さらに,以下の問題に対するプログラムを作成してこちらを提出せよ.

マクローリン展開 ex = 1 + x1/1! + x2/2! + x3/3! + x4/4! + … を利用して指数関数 ex の値の近似値を計算する double myexp( double x ) を作成せよ. xk / k! < 10-6 となった時点で計算を打ち切ることで, ex = 1 + x1/1! + x2/2! + … + xk/k! を出力すること.

表示例:(全体で 13 桁,小数点以下 5 桁で表示せよ).
     x      myexp(x)
   1.0       2.71828
   2.0       7.38906
   3.0      20.08554
   4.0      54.59815
   5.0     148.41316
   6.0     403.42879
   7.0    1096.63316
   8.0    2980.95799
   9.0    8103.08393
  10.0   22026.46579
(E5_A)

「キックオフ C言語」 7.4節 練習問題 4(【1組の値を返すペアの関数】分数の足し算…)に解答せよ.作成した関数を利用し,動作が確認できるような C 言語のプログラムを作成して提出すること.

(E5_B*)

「キックオフ C言語」 12.1節 練習問題「6章」(is_coin_note, get_coin_note)に解答せよ.作成した関数を利用し,動作が確認できるような C 言語のプログラムを作成して提出すること.