Ex11

From Prog0

Jump to: navigation, search

演習第11回

Contents

演習問題

主な内容

  • 関数の呼び出しと定義
  • 引数・仮引数・戻り値
  • プロトタイプ宣言

なお、一人ひとりの授業理解度を確認することを目的として、口頭試問形式による採点を行います。
採点対象の問題が解けたら手を挙げ、教員またはTA/SAを呼んでください。口頭で解答の内容を説明してもらいます。
正しく説明できた場合は点数を付け、説明が不十分な場合はやり直してもらいます(間違えても減点はしません)。
今回の口頭採点の対象は A-2 の1問のみです。 (口頭採点の対象も、その他の問題と同様、menuコマンドで提出してください。)

出席確認

演習時間中に出席確認をLMS上の「演習出欠」で行ってください。出席確認用のパスワードは演習時間のどこかのタイミングで提示されます。


A問題

A-1 関数の基礎

ファイル名: ex11a1.txt

以下の問いに答えなさい。答えは ex11a1.txt に記入すること。

  • 関数を使用することによる利点とは?
  • 実引数と仮引数の違いは何か?
  • 戻り値とは何か?
  • ローカル変数とは何か?

A-2 関数の使い方(口頭試問)

ファイル名: ex11a2.c

次のプログラムは、1人の学生の数学と英語の点数(整数)を標準入力から受け取り、 関数 weighted_average によって加重平均(数学60%、英語40%)を計算し、 その平均点に基づいて関数 evaluate_grade により評価を求めて表示するものです。
評価の基準は以下のとおり:

  • 平均点が85点以上:評価 1
  • 平均点が70点以上85点未満:評価 2
  • 70点未満:評価 3

実行例を参考にし、下線部を埋めてプログラムを完成させなさい。

#include <stdio.h>

double weighted_average(_____, _____);
int evaluate_grade(_____);

int main()
{
  int math, english;
  double avg;
  int grade;

  printf("数学と英語の点数(整数)を入力してください: ");
  scanf("%d %d", &math, &english);

  avg = weighted_average(____, ____);
  grade = evaluate_grade(_____);

  printf("加重平均: %.1f\n", ____);
  printf("評価: %d\n", ____);

  return 0;
}

double weighted_average(_____, _____)
{
  return (__________);
}

int evaluate_grade(double score)
{
  if (______)
    return 1;
  else if (______)
    return 2;
  else
    return ____;
} 

[実行例]

% ./a.out
数学と英語の点数(整数)を入力してください:90 95
加重平均: 92.0
評価: 1 
% ./a.out
数学と英語の点数(整数)を入力してください:68 79
加重平均: 72.4
評価: 2 
% ./a.out
数学と英語の点数(整数)を入力してください:26 19
加重平均: 23.2
評価: 3
%

A-3 scanfの戻り値

ファイル名: ex11a3.txt

scanfの戻り値が入力値を読み込んだ引数の個数になることを確認する。以下のプログラムをコンパイルし、次に示す値の組を使ってそれぞれ実行せよ。それぞれの入力について実行結果を ex11a3.txt に記入しなさい。

#include <stdio.h>

int main()
{
  int a, b, value;

  printf("数値を2つ入力してください:");
  value = scanf("%d%d", &a, &b);
  printf("value = %d, a = %d, b = %d\n", value, a, b);

  return 0;
}

入力値は以下を使用すること(<Ctrl+d>はコントロールキーを押しながら「d」を押す)。

6    7
3    2.8
4.4  6.3
5.2  2
1    a
a    9
<Ctrl+d>

例えば、scanf("%d%d",&i, &j) の戻り値は、

  • 0(全く読み込めなかった)
  • 1(1個だけ読み込めた)
  • 2(2個読み込めた)

のどれかになる。ただし、整数型の入力に対して浮動小数点の値が入力されると、整数部分だけは読み込みに成功して読み込んだ個数にカウントされる。しかし、残りの小数点以下の入力内容はそのまま残るため、以降の読み込みに悪影響を及ぼし、読み込みの失敗を引き起こしたり、意図しない値の読み込みを生じたりする。また、<Ctrl+d> だけが入力された場合の戻り値は EOF(-1)になる。

B問題

B-1 円錐の体積の計算

ファイル名: ex11b1.c

実行例のように、底面の円の半径と高さを入力して、円錐の体積を計算し表示するプログラムを作成しなさい。その際、二乗を計算するnijou、円の面積を計算する関数circle、円柱の体積を計算する関数cylinder、そして円錐の体積を計算する関数coneを作成して組み合わせて利用すること(円錐の体積は同じ底面積・高さを持つ円柱の体積の1/3である)。なお、円周率PIは3.14としてマクロで定義を行うこと。関数の内容については、ハンドアウトp.57,60のlec11-5, lec11-19にあるように、関数circleの中で関数nijouを、関数cylinderの中で関数circleを呼び出すようにしてください。また、新しくcone関数を作り、その中で関数cylinderを呼び出してください。

[実行例]

% ./a.out
円錐の底面の円の半径と高さをcmで入力してください
半径 高さ: 5.0 3.0
円錐の体積は 78.500000 cm3
%

B-2 数字ピラミッドの作成

ファイル名: ex11b2.c

1〜9の整数nを入力し、各行に行番号(1, 2, 3, ...)の数字をその回数だけ繰り返して、中央揃えの数字ピラミッドを表示するプログラムを作成しなさい。数字ピラミッドの出力は、関数「void print_pyramid(int n)」を作成して実行し、数字と数字の間には1つの空白を入れなさい。また、n が1〜9の範囲外であれば「範囲外の数値です。」と表示して、プログラムを終了しなさい。

[実行例]

% ./a.out
1〜9の整数を入力してください: 5
    1
   2 2
  3 3 3
 4 4 4 4
5 5 5 5 5
%
% ./a.out
1~9の整数を入力してください: 13
範囲外の数値です。
%

B-3 時間差

ファイル名: ex11b3.c

キーボードから入力した2つの時刻の時間差を計算し、以下の実行例のように表示するプログラムを作成しなさい。ただし、時刻の時・分・秒を表す3つの整数値を引数として受け取り、0時0分0秒から数えた秒数を戻り値とする関数 sectime を作成して使用すること。なお、時刻2は必ず時刻1よりも後の時刻であると仮定してよい。

[実行例]

% ./a.out
時刻1の時・分・秒を整数値で入力してください:13 10 10
時刻2の時・分・秒を整数値で入力してください:14 30 40
時刻1は0時0分0秒から数えて 47410 秒
時刻2は0時0分0秒から数えて 52240 秒
時刻1と時刻2の時間差は 1 時間 20 分 30 秒です
%

Extra問題

E-1 円周率 π を求める

ファイル名: ex11e1.c

円周率 π を求めるために以下の式を使うことにする。

π=4 tan-1 1

この tan-1(アークタンジェント、タンジェントの逆関数)を計算する方法であるが、C言語には組み込み関数の atan が存在する。しかしせっかくなので、ここでは私たちの手で計算することを考えてみよう。

tan-1 は以下のようにして計算することができる。

tan-1 x = x - x3 / 3 + x5/ 5 - x7 / 7 + ...

この式を利用して tan-1 を計算する関数 arctan を作り、実際に π が計算できるかどうかを確認してみよう。

手法は以下の通りである。

  • 指定された級数のベキ乗まで tan-1 1 の値を求めて返す関数 arctan を作成する。
  • 関数arctanの仮引数はベキの上限を表す変数(int型)、戻り値は計算した tan-1 1 の値(double型)とする。
  • main関数の中でベキの上限値を奇数で入力させ、この数を関数 arctan に渡して結果を表示する。

計算結果の例を以下に示す(環境によって数値が若干変化する場合がある)。

% ./a.out 
級数の計算上限となる数を奇数で入力して下さい: 101
101まで計算した場合の pi の値: 3.161199
% ./a.out
級数の計算上限となる数を奇数で入力して下さい: 1001
1001まで計算した場合の pi の値: 3.143589
% ./a.out
級数の計算上限となる数を奇数で入力して下さい: 10001
10001まで計算した場合の pi の値: 3.141793
% ./a.out
級数の計算上限となる数を奇数で入力して下さい: 100001
100001まで計算した場合の pi の値: 3.141613
% ./a.out
級数の計算上限となる数を奇数で入力して下さい: 1000001
1000001まで計算した場合の pi の値: 3.141595
%

なお、この計算方法では計算の収束が遅いことが知られているため、上の例のように数をかなり大きくしないと、π の値にはなかなか近づかない。

課題提出上の注意事項

解答ファイルはmenuコマンドを使って提出してください。以下のようにmenuコマンドを実行し、表示されるメッセージに沿って操作すること。

% ~prog0/bin/menu

menuコマンドは、解答ファイルが ~/Prog0/Ex## のディレクトリに指定されたファイル名で置かれているものとして処理します。正常に提出された場合は ○ が、何らかのエラーが生じた場合は × が表示されます。

解答の提出期間は以下のとおりです。

問題提出受付開始提出〆切
A問題 演習日の6日前の午後9時演習終了時刻
B, Extra問題 演習日の6日前の午後9時演習日の6日後の午後9時

提出は〆切前であれば何度でもやり直すことができます。再提出すると、前に提出したファイルは新しい内容で上書きされます。

Personal tools