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

[E5] 第5章 関数(2)


「グローバル変数」は便利な面もあるが,プログラミングのミスにより意図と異なる値の書き換えなどを犯してしまいがちで,使用には注意が必要である.特に 今回は「関数」の習得が目標であり,引数・戻り値の概念を理解することが重要であるため,宿題課題[E5]ではグローバル変数を用いずに解答して下さい.

(E5_1) [リスト 5.17] および 3.1節を参考にして,整数 m の階乗を求めるプログラムを作成する.正しい数値が表示されない場合は,その理由などを考察してレポートに記すこと.

表示例
          fact   lfact
-----------------------------
   1!  =    1      1
   2!  =    2      2
   3!  =    6      6
   4!  =   24     24
           :
  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) [リスト5.17] を参考にして,main 関数にて 12 以下の整数 n をキーボードから受け取った上で, nC0nC1,…,nCn を表示するプログラムを作成せよ.nCiは n 個から i 個を選ぶ組合せの数を指す.

 表示例( n = 10 )

 10 C 0 = 1
 10 C 1 = 10
 10 C 2 = 45
 10 C 3 = 120
 10 C 4 = 210
 10 C 5 = 252
 10 C 6 = 210
 10 C 7 = 120
 10 C 8 = 45
 10 C 9 = 10
 10 C 10 = 1

(E5_3) 確率 p で当たりが出るくじを n 回引くとき,当たりが i 回出る確率は nCi pi ( 1-p )n-i である.main 関数でキーボードから 12 以下の整数 n と,1.0 未満の正の実数 p を受け取り,上の確率を i = 0, ..., n に対して表示するプログラムを作成せよ.
x の i 乗 xi を求める関数 double powdbl( double x, int i ) は [T4] で扱った関数 powint を参考にして自作すること.また,必要に応じてこれまでに作成した関数を使用してよい.

 表示例( 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_4) まず,[リスト 5.11] を入力した上で実行せよ.[リスト 5.11] の mysqrt は,

という数列が x の平方根に収束することを利用して計算を行っている.
このプログラムに, x の 3 乗根を計算する関数 double mycbrt( double x ) を追加せよ. 数列には, を用いればよい.
さらに,main 関数では,mysqrt に続いて mycbrt を呼び出す. mysqrt に対する表示は [実行結果 5.11] と同じものでよい. mycbrt に対する表示は,x = 1, 2, 3, …, 10 について x の 3 乗根 r と r の 3乗 を表示することで,r が確かに x の 3 乗根であることを確認すること.

(E5_5) 与えられた 4 個の整数の最小値と最大値を求める関数を作成する.


(E5_6) 指数関数 f(x)= ex の x = a における微分係数を近似的に求めるプログラムを作成する.

f(x)の導関数を f'(x) として,f'(a) = ea の近似値が得られているか,確認すること.
出力例

a = 0.0
--------------------------------------------
g(0.000000, 1.0000000000) = 1.7182818285
g(0.000000, 0.5000000000) = 1.2974425414
            :
g(0.000000, 0.0000038147) = 1.0000019073
g(0.000000, 0.0000019073) = 1.0000009537
a = 1.0
--------------------------------------------
g(1.000000, 1.0000000000) = 4.6707742705
g(1.000000, 0.5000000000) = 3.5268144838
            :
g(1.000000, 0.0000038147) = 2.7182870131
g(1.000000, 0.0000019073) = 2.7182844207

#include <stdio.h>

int main( void )
{
    int i, w;
    double h;

    w = 1;
    for( i = 0; i < 20; i ++ ){

        h = 1.0 / (double)w;
        printf("%d \t %.25f \n", w, h);  /* コメントアウトすること */






        w *= 2;

    }

  return 0;
}


(E5_7) 下のプログラムについて,次をレポートに記せ.

  1. 実行結果を予想せよ.
    次の ? の部分を予想する値で埋め,「...の」の部分に「グローバル変数の」「mainのローカル変数の」「incのローカル変数の」のいずれかを記入せよ.
      (inc  1) a = ?   ...の a
      (inc  2) b = ?   ...の b
      (main 1) a = ?   ...の a
      (inc  1) a = ?   ...の a
      (inc  2) b = ?   ...の b
      (main 2) b = ?   ...の b
      (main 3) c = ?   ...の c
    
  2. 実際にこのプログラムを入力,コンパイル,実行せよ.
    結果をレポートに記し,各行に前項と同じように「...の a」等の説明を付け加えよ.
#include <stdio.h>

int a;

void inc( int );
void set_a( int );
int get_a( void );

int main( void )
{
	int a, b, c;
	/* 本問では,変数のスコープの理解のためグローバル変数と
	   同じ名前のローカル変数を関数内で定義しました.
	   このようなプログラムを書くと問題が生じる可能性がある
	   ため,グローバル変数とローカル変数を同一の名前にする
	   ことは避けるようにして下さい  */

	a = 10;
	b = 20;

	set_a( 100 );

	inc( a );

	printf( "(main 1) a = %3d\n", a );

	inc( b );

	printf( "(main 2) b = %3d\n", b );

	c = get_a();

	printf( "(main 3) c = %3d\n", c );

	return 0;
}

void inc( int b )
{
	a++;
	b++;

	printf( "(inc  1) a = %3d\n", a );
	printf( "(inc  2) b = %3d\n", b );
}

void set_a( int v )
{
	a = v;
}

int get_a()
{
	return a;
}

(E5_8*) ex = 1 + x1/1! + x2/2! + x3/3! + x4/4! + … を利用して ex を計算する関数 double myexp( double x ) を作成せよ. k=0, 1, 2, 3, … について xk/k! を加算していき,xk/k!<10-6 となった時点で計算を打ち切るようにせよ (pp. 166〜167 の無限ループと break 文を用いるのが一方法). main 関数から関数 myexp を呼び出し,x=1.0, 2.0, …, 10.0 に対して myexp(x) の値を全体で 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節 練習問題 3(【信頼性】正の整数 x, y の最大公約数を…)を解答せよ.
作成した関数を利用し,動作が確認できるような C 言語のプログラムを作成して提出すること.

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