Ex11

From Prog0

Jump to: navigation, search

演習第11回

Contents

演習問題

主な内容

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

以下の問題を解いて期限内に解答を提出してください。

出席確認

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


A問題

A-1 関数の基礎

ファイル名: ex11a1.txt

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

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

A-2 関数の使い方

ファイル名: ex11a2.c

以下のプログラムは標準入力した値を変数 n に格納し、それを関数 square を渡して二乗し、二乗した値を変数 m に代入する。さらに m の逆数を関数 recipro で計算して変数 res に代入する。最後に n, m, res の値を出力する。実行例も参考にし、下線部を埋めてプログラムを完成させなさい。

#include <stdio.h>

int square(_____);
_____ recipro(_____);

int main()
{
  int m, n;
  double res;

  printf("整数値を入力してください:");
  scanf("%d", &n);

  _____ = square(n);
  _____ = recipro(_____);

  printf("n = %d, m = %d, res = %f\n", n, m, res);

  return 0;
}

_____ square(_____)
{
  return x*x;
}

_____ recipro(int x)
{
  return 1/_____;
}

[実行例]

% ./a.out
整数値を入力してください:5
n = 5, m = 25, res = 0.040000
%

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」を押す)。

3    5
2    4.6
3.2  6.7
5.2  8
3    a
a    5
<Ctrl+d>

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

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

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

B問題

B-1 関数の引数

ファイル名: ex11b1.c

入れる紅茶の杯数 n を入力すると、スプーン (n + 1) 杯の茶葉をポットに入れる様子を表示する関数 teaspoon を定義し、それを使って、以下の実行例のように動作するプログラムを作成しなさい。0 を入力したら終了とする。

[実行例]

% ./a.out
紅茶の杯数を入力してください:1
1さじ、2さじ
お湯を注ぐ・・・
お茶をどうぞ!
紅茶の杯数を入力してください:3
1さじ、2さじ、3さじ、4さじ
お湯を注ぐ・・・
お茶をどうぞ!
紅茶の杯数を入力してください:0
またどうぞ
%

B-2 関数の戻り値

ファイル名: ex11b2.c

double型の正の値を、小数点以下の指定した桁数までとなるように四捨五入する関数 round_to を作成し、それを使って、キーボードから入力した実数を、指定した桁数までとなるように四捨五入して表示するプログラムを作成しなさい。

[実行例]

% ./a.out
正の実数値を入力してください:3.14159265
小数点以下の桁数を入力してください:2
3.140000
% ./a.out
正の実数値を入力してください:3.14159265
小数点以下の桁数を入力してください:4
3.141600
%

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