A問題(50点)
講義で学んだ、関数の引数としてポインタを与える「アドレス渡し」と、関数の引数として配列の先頭アドレスを与える方法を確認しよう。
ptr_avesub() は、mainで入力された値を格納した3つの変数へのポインタを引数として受取る。3つの値の平均値を計算し、平均値を戻り値とする。さらに、引数であるポインタ変数を介して各入力値を平均からの差分の値に書き換える。
ptr_avesub()関数の中で書き換えられた平均からの差分を出力する。
#include <stdio.h>
______ ptr_avesub(________, ________, ________); /* プロトタイプ宣言 */
int main()
{
double a, b, c, ave;
printf("3つ値を入力してください:\n");
scanf("%lf%lf%lf", &a, &b, &c);
printf("入力された値: %.2f %.2f %.2f\n", a, b, c);
_____ = ptr_avesub( _____, ______, _____ ); /* 関数の呼び出し */
printf("平均(%.2f)からの差分: %+.2f %+.2f %+.2f\n", ave, a, b, c);
return 0;
}
/* 平均を計算して戻り値とするとともに、ポインタ渡しされた値も平均からの差分に書き換える関数。 */
______ ptr_avesub(________, ________, ________)
{
/* ここを適宜作成 */
}
実行例
% ./a.out 3つ値を入力してください: 1.0 3.0 5.0 入力された値: 1.00 3.00 5.00 平均(3.00)からの差分: -2.00 +0.00 +2.00 % ./a.out 3つ値を入力してください: 5.0 9.0 -6.5 入力された値: 5.00 9.00 -6.50 平均(2.50)からの差分: +2.50 +6.50 -9.00
2. 同じ機能をもつプログラムを、配列を利用して作成したい。
新しい仕様に合うように、プログラムの空欄を埋めて完成させなさい。
(提出ファイル名: prog01b.c)
仕様
arr_avesub() は、mainで入力された値を格納した配列の先頭アドレス(配列へのポインタ)を引数として受取る。配列中の3つの値の平均値を計算し、平均値を戻り値とする。さらに、引数を介して配列中の各入力値を平均からの差分の値に書き換える。
arr_avesub()関数の中で書き換えられた平均からの差分を出力する。
#include <stdio.h>
______ arr_avesub(________); /* プロトタイプ宣言 */
int main()
{
double data[3], ave;
printf("3つ値を入力してください:\n");
scanf("%lf%lf%lf", _____, _____, _____);
printf("入力された値: %.2f %.2f %.2f\n", data[0], data[1], data[2]);
_____ = arr_avesub( _____ ); /* 関数の呼び出し */
printf("平均(%.2f)からの差分: %+.2f %+.2f %+.2f\n", ave, data[0], data[1], data[2]);
return 0;
}
/* 平均を計算して戻り値とするとともに、ポインタ渡しされた値も平均からの差分に書き換える関数。 */
______ arr_avesub(__________)
{
/* ここを適宜作成 */
}
実行例は前と同じである。
B問題(50点)
コマンドライン引数として得点(評点)をいくつか与えると、実行例のようにその評価 (A/B/C/D/F)を出力するプログラムを作成しなさい。 (得点と評価の対応は、 A: 80~100点, B: 65~79点, C: 50~64点, D: 35~49点, F: 35点未満)
なお、得点から評価への変換には、
演習第1回問題3
で作成した関数を流用してもよい。
また、コマンドライン引数には評点をいくつ書いても良いこととし、引数が無い場合は何もせずに終了する。
なお、評点として0から100までの整数以外が入力された場合の処理は考えなくてよい。
(提出ファイル名: prog02.c)
% ./a.out 100 79 64 34 48 評点:100 評価: A 評点: 79 評価: B 評点: 64 評価: C 評点: 34 評価: F 評点: 48 評価: D % ./a.out %
atoi()
を用いると良い。関数 atoi の引数は文字ポインタ、戻り値は int型である。
なお、この関数を使用するには、 stdlib.h
をプログラムの最初でインクルードしておく必要がある。
正の整数による数値の列(つまり等差数列)を作る事を考える。なお、数列は増加するものとする。
開始値(初項)と上限値、及び刻み(公差)をもとに、開始値から刻み分を順次加算した値を作り、上限値を超えない値を並べて数列を作ることにする。
例えば開始値が 2、上限値が 10、刻みを 2とすると、
2 4 6 8 10
一方、例えば開始値が 1、上限値が 12、刻みを 2とすると、
1 3 5 7 9 11
この考え方に基づいて、開始値と上限値、及び刻み(いずれもint型の正の整数)を入力すると、数列を格納するのに必要なサイズのメモリを 動的メモリ割り当てによって作成してそこに数列の値を格納し、その値を表示するプログラムを作成しなさい。以下に示すプログラムの雛形を使うこと。
なお、動的メモリ割り当ての前に、数列の長さと確保すべきメモリサイズを求めて表示すること。
また、開始値と上限値、刻みの関係に関するエラーチェックはしなくてよい(例えば開始値より上限値の方が小さいのに、刻みが正である場合など)。
動的メモリ割り当てで確保するメモリは「数列の長さ」に応じた必要最小限のサイズとすること。
(提出ファイル名: prog03.c)
% ./a.out Input start, stop, and step of the sequence: 2 10 2 Length: 5 Memory to be allocated (Byte): 20 Sequence: 2 4 6 8 10 % ./a.out Input start, stop, and step of the sequence: 1 12 2 Length: 6 Memory to be allocated (Byte): 24 Sequence: 1 3 5 7 9 11 %プログラム雛形:
#include <stdio.h>
#include ________
int main()
{
int length, i;
int start, stop, step;
int *array;
/* 開始値、上限値、刻みを入力 */
printf("Input start, stop, and step of the sequence: ");
scanf("%d%d%d", &start, &stop, &step);
/* 数列の長さ、必要なメモリサイズを計算、表示 */
/* メモリ確保 */
/* 確保したメモリへの数列の値の保存 */
/* 結果の表示 */
/* 確保したメモリの使用終了後の処理 */
return 0;
}
Extra問題
% ./a.out test text.in x.in.in hoge.out prog.c test -> test.out text.in -> text.out x.in.in -> x.in.out hoge.out -> hoge.out.out prog.c -> prog.c.out %
テキストファイルに書かれている単語を読みこみ、
その単語を編集してファイルに保存するプログラムを作成する。
(提出ファイル名: prog05.c)
このプログラムはコマンドライン引数を2つ受け取り、
最初の引数を入力ファイル名、2番目の引数を出力ファイル名とする。
まず、入力ファイルから、空白で区切られた単語を1つずつ読みこんで記憶するが、
単語の長さはまちまちであるため、下図のような可変長二次元配列を使う。
この問題での可変長二次元配列は、1024要素のポインタの配列と、動的に確保したメモリ領域を使って実現する。
単語を読み込む手順は以下のようになる。
図:可変長二次元配列
次に、以下のコマンドを受け付けながら、単語を編集していく。編集中は end 以外のコマンドは何度も受け付けるようにする。
実行例 (テスト用入力:uoa.in)
% cat uoa.in The University offers one of top-class computer education in Japan % ./a.out uoa.in uoa.out >show 0: The 1: University 2: offers 3: one 4: of 5: top-class 6: computer 7: education 8: in 9: Japan >insert 2 of >insert 2 Aizu >show 0: The 1: University 2: Aizu 3: of 4: offers 5: one 6: of 7: top-class 8: computer 9: education 10: in 11: Japan >swap 2 3 >remove 8 >show 0: The 1: University 2: of 3: Aizu 4: offers 5: one 6: of 7: top-class 8: education 9: in 10: Japan >end % cat uoa.out The University of Aizu offers one of top-class education in Japan %