Top / AProg / 2014 / ex05

応用プログラミング演習 2014年度 第5回 [edit]

注意 [edit]

  • 演習のすすめ方について AProg/2014/ex01#note?
  • Linux環境での操作についてはわからないことがあったら Docs/4UNIXBeginners

課題A(self) 完成目標: 今回の演習終了まで [edit]

構造体を使ってみよう

番号名前年齢視力
3Uni1000.1
1055Hogeo431.2
666Henako185

構造体を利用して,上記の各行をひとまとまりのデータとみなして処理するプログラムを作ろう. ただし,次の条件を満たすようにすること.

  1. ソースファイル名は ex05a.c とする.
  2. 次の内容のテキストファイル(ファイル名を data4ex05a.txt とする)があったとする.
    3 Uni 100 0.1
    1055 Hogeo 43 1.2
    666 Henako 18 5
    
    これを入力としてこのプログラム(実行形式のファイル名を ex05a とする)を次のように実行すると次の出力が得られる.
    $ ./ex05a < data4ex05a.txt
    num: 3  name: Uni  age: 100  sight: 0.1
    num: 666  name: Henako  age: 18  sight: 5.0
    num: 1055  name: Hogeo  age: 43  sight: 1.2
    
    • 元のファイルと順序が入れ替わっている箇所があることに注意.
    • nameの文字列は,名前に最大99文字使えるように大きさを考えること.
      • check char型の配列の長さはいくつにすればよい?
    • 視力の数値の表示形式に注意.
      • check printfでどのような書式指定文字列("%03d"みたいなもの)を書けばよい?
  3. 上述の結果が得られるように,次のようなプログラムを作成すること.
    • 構造体の変数も配列にできるので,配列を使いたくなるかもしれませんが,ここではばらばらの変数を使えばよいです(構造体の変数の配列を扱う演習問題は,次回登場します).
      #include <stdio.h>
      
      「ひとり分のデータを格納するための構造体を定義する」(typedefを使って適当な型名をつけること)
      
      int main(void)
      {
        「構造体変数の宣言」
      
        scanf("%d %s %d %lf", 「ひとつめの変数に値を入れる」);
        scanf("%d %s %d %lf", 「ふたつめの変数に値を入れる」);
        scanf("%d %s %d %lf", 「みっつめの変数に値を入れる」);
        
        「3つの変数のうち2つの内容を入れ替える」(構造体を使う利点をいかすこと)
      
        printf( 「ひとつめの変数の内容を表示」 );  
        printf( 「ふたつめの変数の内容を表示」 );  
        printf( 「みっつめの変数の内容を表示」 );  
      
        return 0;
      }
      

課題B(TA) 今回の演習終了20分前 [edit]

ひとの作ったプログラムを利用してみよう

step0 [edit]

次のように cp コマンドを実行すると,prime.h と prime.c という二つのファイルを入手できる.

$ cp /home/sample/takataka/aprog2014/prime.*    .     ← ピリオド

ちなみにこのコマンドを実行すると何がおこるかを説明すると…

  1. 「*」は,「0文字以上の任意の文字」を表すので,prime.h と prime.c の両方がコピー元に指定される(もしも上記ディレクトリ内に他にも prime.hoge とかいうファイルがあったとしたらそれも).
  2. コピー先の指定が「.」つまりカレントディレクトリなので,コピー元のファイルたちは名前を変えずにカレントディレクトリにコピーされる

ということになっている.

check 「*」や「?」(こちらは任意の1文字を表す)の解釈はシェル(端末上でキー入力を解釈してOSに渡す仕事をするプログラム)が行っているので,cp 以外のコマンドでもこの技は使える.

$ ls *.c
$ ls ex??x999.c

などを実行してみるとよい.ちなみに,次のように実行すると大変なことになる.やっちゃだめですよ.絶対やっちゃだめですよ.

$ rm *

コピーができたら,次のことをしなさい.

  • lsコマンドを実行して本当にコピーできたことを確認
  • emacs または less でこれらのファイルの中身を眺めてみる

以下のstepでは,この2つのファイルを利用するプログラムを作成する. その際には,prime.h と prime.c は利用するだけで,それらの中身は変更しない ようにすること.

step1 [edit]

次のような動作をするプログラムを作りなさい.

  • 自分で作成するソースファイルの名前は ex05prime.c とすること.
  • 入力された数は配列に格納すること.数の個数は100以下と仮定してよい.
$ ./ex05prime 
何個?:  6   ← 6 はキーボードからの入力
0番目: 7     ← 7はキーボードからの入力.以下同様
1番目: 2
2番目: 1024
3番目: 1023
4番目: 8192
5番目: 8191
素数は3個    ← プログラムの出力

step2 [edit]

prime.c や prime.h を見るとわかるように,prime.c には三つの関数が定義されている. step1のプログラムでは,そのうちひとつはmain()から呼び出されており,もう一つはその関数から呼び出されているが,残りひとつの関数は全く使われていないはずである. step1のプログラムを改造し,その関数をmain()の適当な位置で呼び出すようにしなさい.

課題C(TA) 締切: 次回の演習開始直後 [edit]

次のような動作をするプログラムを作成しなさい.

$ ./ex05search
線形探索するよん
0以上の整数から成るデータを扱えるよん
データは何件やねん?: 5                                   
0番目のデータ(0以上の整数)を入力してねん: 10
1番目のデータ(0以上の整数)を入力してねん: 37
2番目のデータ(0以上の整数)を入力してねん: 26
3番目のデータ(0以上の整数)を入力してねん: 10
4番目のデータ(0以上の整数)を入力してねん: 123
データは5件やねん
キー値を入力してねん(負の数やと終了すんねん): 37
その値は1番目にあるよん
キー値を入力してねん(負の数やと終了すんねん): 10
その値は0番目にあるよん
キー値を入力してねん(負の数やと終了すんねん): 36
その値はないねん
キー値を入力してねん(負の数やと終了すんねん): -2
ばいばい

ただし,以下の指示に従うこと.

  • ソースは次の3つのファイルから成るものとする
    • 関数 main の定義を含むソースファイル ex05lsearch.c (linear search の略でエルサーチ,つまりエルの小文字です)
    • 関数 LSearch の定義を含むソースファイル lsearch.c (ファイル名の先頭はエルの小文字です)
    • 関数 LSearch のプロトタイプ宣言を含むヘッダファイル lsearch.h
  • データ件数は最大100件まで扱えるようにすればよい
  • 入力されるデータが0以上の整数であるかどうかのチェックは,省略して構わない(余裕のある人は,このプログラムではなぜこのような条件が必要なのかを考えるとともに,チェックするように(負数を入力すると再入力を促すとか)改良してみるとよい)
  • 関数 LSearch は次のような仕様とする(関数LSearchの定義を紙に書いてチェック時に見せること
    • 引数は,int型配列,その要素数,キーの値,の3つ
    • 配列中にキーの値と一致する要素が見つかればその番号(配列の添字)を返し,見つからなければ-1を返す
    • 探索アルゴリズムは線形探索とする
    • この関数中ではscanfもprintfも使わない(デバグ中は別ですが)
    • 配列中に同じ値が複数含まれている場合のことは考慮しなくてよい(上記の実行例からわかるように,最初に見つけたものの番号を返すようにしておけばよい)

ヒント: mainの側での1回の探索の手順はこんな感じですね(白字で書いてあります.読みたいときはマウスで文字列を選択してみよう)

  1. キー値を入力してもらう
  2. それが負だったらほげほげ
  3. LSearchを呼ぶ
  4. 見つけたかどうかに応じてほげほげ

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2014-10-27 (月) 12:57:16 (1063d)