第06回の課題の解答例

プログラミング言語 2 第 06 回 6/11 回答例
氏名 学籍番号 問題 1: 次の使用を満たす関数 sample02 を作成しなさい。
問題 2 で提出するプログラム中に含まれることになるので、単独で答えを書かなくても良い。
•
引数として、3 つの double 型の値 x, y, z と、double 型の変数 w のアドレスを貰う。
•
戻り値として、double 型の値
•
関数呼び出し終了時の変数 w の値は、 2  x とする。
 x y ×ln  z ×cos 1.5
∣cos  y∣
を返す。
問題 2: 以下の仕様を満たすプログラムを、問題 1 の結果をふまえて、作成しなさい。
手書きではなく、別途印刷したものを提出すること。
要求 1: input.txt に、入力データが書いてある。
•
input.txt は、10 行からなっている。
•
input.txt の、各行には、スペースで区切られて 3 つの double 型の値が並んで
いる。
1 つめの値から順に、x, y, z とする。
要求 2: 標準出力に以下を出力する。
•
•
1 組の x, y, z に対して、1 行の出力を行う。
各行には、 2  x
と
 x y ×ln  z ×cos 1.5
∣cos  y∣
がスペースで区切られて出力する。
問題 3: 問題 2 の出力結果を xgraph でグラフにしなさい。
つまり、input.txt に対する

2 x ,
 x y ×ln z ×cos 1.5
∣cos  y ∣

のグラフを書きなさい。
この授業について、ご意見ご感想、もっと説明して欲しいところ等、何かあったらお書きください。
注: このシートは、6/10 の授業の出欠を兼ねています。
今回の課題について
今週は、一度に色々な話が出たため、難しい課題でした。今週と来週で、頭の中を整理し
ておきましょう。
プログラム例:
01:
02:
03:
04:
05:
06:
07:
08:
09:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
#include<stdio.h>
#include<math.h>
double sample02(double x, double y, double z, double *w){
*w= 2*sqrt(x);
return (sqrt(pow(x,y))*log(z)*cos(1.5))/fabs(cos(y));
}
main(){
int i;
double x,y,z,w;
double value;
for(i=1;i<=10;i++){
scanf("%lf%lf%lf",&x,&y,&z);
value=sample02(x,y,z,&w);
printf("%f %f\n", w, value);
}
}
プログラムの解説
main 文の中から見ていきます。
第 11 行目。今回は、x,y,z,w という 4 つの変数が出てきましたので、main 文の中でも、4 つの変数
を宣言しています。
第 12 行目。関数 sample02 の戻り値を貰うための変数 value を宣言しています。
第 14~18 行目。入力テキストは 10 行あります。1 回の scanf で 1 行文のデータを読み込むことに
すると、全部で 10 回、繰り返せばよいことになります。
第 15 行目。問題ではファイルから入力を貰わないといけないのですが、リダイレクトを使っ
て、ファイルの中身を標準入力として入力することにします。だから、ここは fscanf ではなく、
scanf を使用することにします。
第 16 行目。関数 sample02 をつかって、 2  x
と
 x y ×ln  z ×cos 1.5
を計算します。
∣cos  y∣
 x y ×ln  z ×cos 1.5 が、w には 2  x が返っ
sample02 の仕様によれば、戻り値として
∣cos  y∣
てきます。
第 17 行目。標準出力に 2  x
と
 x y ×ln  z ×cos 1.5
を出力します。printf は、標準
∣cos  y∣
出力に出力を行う命令です。標準出力は、ここの環境ではコンソールなので、画面に表示
が出ます。
次に、sample02 の中を見てみます。
第 04 行目。引数として、3 つの double 型の値 x, y, z と、double 型の変数 w のアドレスを貰うこと
になっていますので、対応する 4 つの変数と型を書かなくてはいけません。今回は x,y.z,w としま
したが、別に他の名前でも構いません。また、4 つめの引数はアドレスが来るのでポインタを宣言し
ています。x,y,z は値渡し、*w はアドレス渡しがされているということを、確認しておきましょう。つま
り、x,y,z は関数 sample02 内で値を変更しても、main 関数内の変数に影響を与えません。一方、
*w の値は関数 sample02 内で値を変更すると、main 関数内の変数の値も変わります。
第 05 行目。*w の値を 2  x にします。
第 06 行目。戻り値として
 x y ×ln  z ×cos 1.5
∣cos  y∣
を返します。
プログラムのポイント
幾つか注意すべき点や、間違いやすい点を上げておきます。
●
問題がわるかったため、大域変数とローカル変数がごっちゃになったプログラムを
書いている人が多かったようです。次回からは、題意にあったかたちで、指定指定
したいと思います。
●
第 04 行目で、関数の引数の型を宣言するときは、変数毎に型を宣言する必要があ
ります。double x,y,z のように、まとめて宣言することはできません。『典型的
なリファレンス』の回の『その 2』の書き方と一緒です。
●
printf は、『標準出力に出力する』命令です。ですので、問題の「標準出力に出
力せよ」に対しては、printf を使用すればよいです。
●
sample02 のなかで、4 つめの引数だけは、アドレス渡しをしています。これは、
sample02 から 2 つの計算結果を貰いたいのに、戻り値としては 1 つしか貰えないの
で、残りの 1 つを 4 つめの引数に返して貰うためです。