A問題(50点)
講義で学んだ、関数の引数としてポインタを与える「アドレス渡し」と、関数の引数として配列の先頭アドレスを与える方法を確認しよう。
aveandsub_ptr()
は、mainで入力された値を格納した3つの変数へのポインタを引数として受取る。3つの値の平均値を計算し、戻り値とする。さらに、引数であるポインタ変数を介して各入力値を平均からの差分の値に書き換える。
aveandsub_ptr()
関数の中で書き換えられた平均からの差分を出力する。
#include <stdio.h> ______ aveandsub_ptr(________, ________, ________); /* プロトタイプ宣言 */ int main() { double a, b, c, ave; printf("3つ値を入力してください:\n"); scanf("%lf%lf%lf", &a, &b, &c); _____ = aveandsub_ptr( _____, ______, _____ ); /* 関数の呼び出し */ printf("平均: %.3f\n", ave); printf("平均からの差分: %+.3f %+.3f %+.3f\n", a, b, c); return 0; } /* 平均を計算して戻り値とするとともに、ポインタ渡しされた値も平均からの差分に書き換える関数。 */ ______ aveandsub_ptr(________, ________, ________) { /* ここを適宜作成 */ }実行例
% ./a.out 3つ値を入力してください: 1.0 3.0 5.0 平均: 3.000 平均からの差分: -2.000 +0.000 +2.000 % ./a.out 3つ値を入力してください: 5.0 9.0 -6.5 平均: 2.500 平均からの差分: +2.500 +6.500 -9.000
2. 同じ機能をもつプログラムを、配列を利用して作成したい。
新しい仕様に合うように、プログラムの空欄を埋めて完成させなさい。
(提出ファイル名: prog01b.c)
仕様
aveandsub_arr()
は、mainで入力された値を格納した配列の先頭アドレス(配列へのポインタ)を引数として受取る。配列中の3つの値の平均値を計算し、戻り値とする。さらに、引数を介して配列中の各入力値を平均からの差分の値に書き換える。
aveandsub_arr()
関数の中で書き換えられた平均からの差分を出力する。
#include <stdio.h> ______ aveandsub_arr(________); /* プロトタイプ宣言 */ int main() { double data[3], ave; printf("3つ値を入力してください:\n"); scanf("%lf%lf%lf", _____, _____, _____); _____ = aveandsub_arr( _____ ); /* 関数の呼び出し */ printf("平均: %.3f\n", ave); printf("平均からの差分: %+.3f %+.3f %+.3f\n", data[0], data[1], data[2]); return 0; } /* 平均を計算して戻り値とするとともに、ポインタ渡しされた値も平均からの差分に書き換える関数。 */ ______ aveandsub_arr(__________) { /* ここを適宜作成 */ }実行例は前と同じである。
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つの数値の間を等間隔に分割して、数値の列(つまり等差数列)を作る事を考える。
例えば、0.0 から始まり 2.0 で終わる5つの数値を作るとすると、
0.0 から 2.0 の間を 5-1 = 4つの区間に等分することになり、刻み(等差数列の公差に相当する)は 0.5 である。
よって、0.0, 0.5, 1.0, 1.5, 2.0
という数値の列が得られる。
この考え方に基づいて、最初の値、最後の値、数値の個数を入力すると、 「最初の値」~「最後の値」まで等間隔に並ぶ値が格納された配列を 動的メモリ割り当てによって作成し、格納された値すべてを表示し、 さらに各々の値の2倍値も表示する(小数点以下3桁まで;実行例参照)プログラムを作成しなさい。
なお、「最初の値」と「最後の値」は浮動小数点数、「数値の個数」は2以上の整数とする
(エラーチェックはしなくてよい)。
動的メモリ割り当てで確保するメモリは「数値の個数」に応じた必要最小限のサイズとすること。
(提出ファイル名: prog03.c)
% ./a.out 最初の値, 最後の値, 個数を入力: 0.0 2.0 5 数値の列 0.000 0.500 1.000 1.500 2.000 2倍値 0.000 1.000 2.000 3.000 4.000 % ./a.out 最初の値, 最後の値, 個数を入力: 1.0 3.0 11 数値の列 1.000 1.200 1.400 1.600 1.800 2.000 2.200 2.400 2.600 2.800 3.000 2倍値 2.000 2.400 2.800 3.200 3.600 4.000 4.400 4.800 5.200 5.600 6.000 %プログラム例:
#include <stdio.h> #include ________ int main() { int num, i; double v0, vn; double *x; /* 最初の値、最後の値、数値の個数を入力 */ printf("最初の数値, 最後の数値, 個数を入力: "); scanf("%lf%lf%d", &v0, &vn, &num); /* これ以降を作成すること */ /* メモリ確保 */ /* 格納する値の決定。 端の値のぶんを考慮して分割数を決める事と、整数除算しないように注意 */ /* 結果の表示 */ /* メモリ確保したので後処理をする */ 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 %