Top / AProg / 2014 / ex06

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

注意 [edit]

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

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

次のように cp コマンドを実行すると,カレントディレクトリに zssampleL と zssampleB という実行ファイルを入手できる(あらかじめコピー先のディレクトリにcdしておいてから cp を実行すること.また,↓の入力時には途中まで入力したらTabキーを押して補完することを繰り返すと楽ができるでしょう).

$ cp /home/sample/takataka/aprog2014/zssample?  .     ←ピリオド

それぞれ実行してみよう.

check いまどきのコンピュータは速いのでたかだか12万件ちょいの郵便番号データではこの二つの違いは体感できないでしょうが,線形探索の場合と二分探索の場合の探索回数(特に,見つからない場合の)に注目.

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

分割コンパイル,構造体,scanfの戻り値

step1 [edit]

課題Aと同じディレクトリ /home/sample/takataka/aprog2014/ に,data4ex06b.txt という名前のテキストファイルがおいてある. cpコマンドを使ってこれを自分のこの授業用のディレクトリにコピーし,内容を less で確認しなさい. このファイルには,前回の課題A のようなデータが書き込まれている. よく見ると一部おかしなところがあるが,直したりしないでそのまま扱ってみよう.

step2 [edit]

data4ex06b.txt の内容を読み込み,次のような出力をするプログラムを作成しよう.

$ ./ex06b 
4件のデータを読み込んだで
番号: 666  氏名: Henako  年齢: 18  視力: 5.0
番号: 1055  氏名: Hogeo  年齢: 43  視力: 1.2
番号: 999  氏名: Fugayo  年齢: 20  視力: 0.1
番号: 2345  氏名: Piyochan  年齢: 67  視力: 1.0
一番視力が悪いのはFugayo さんです

ただし,次の指示に従うこと

  • ソースファイルは次のような構成とすること
    • ex06b.c 関数 main を定義したソース
    • sight.c 関数 WeakSighted (説明は後述)を定義したソース
    • sight.h 構造体の定義と関数 WeakSighted のプロトタイプ宣言を書いたヘッダ
  • 自分で定義した構造体の変数の配列を用意し,そこにファイルから読み込んだデータを格納するように作ること.
    • 構造体の定義は 前回の課題A と同様
    • 次のように定数Nを定義し,これを構造体変数の配列の大きさとすること
      #define N 50
    • データの読み込みの際にはfscanf()の戻り値を利用してデータ件数をプログラム自身に数えさせること.最大N件読み込めるようにすること.
      • check 上記の実行例でデータ件数が4件となっている理由を答えられますか?
  • sight.c に次のような仕様の関数 WeakSightedを定義し,それを用いたプログラムとすること
    • 引数は構造体変数の配列とその要素数
    • 戻り値は,その配列中で視力が最小のものの要素番号

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

ひとの作ったソースを利用して画像処理をするプログラムを書いてみよう.

step0 [edit]

ディレクトリ /home/sample/takataka/aprog2014/ にある myimage.c と myimage.h というファイルを手元にコピーして,中身を眺めてみよう. この課題では,myimage.c で定義された関数たちがどのような処理を行っているか細かいところまで理解することは求めていない. コメントを手がかりに,これらの関数を呼び出して画像処理するプログラムを作成できればよい.

step1 [edit]

以下はそれらを用いて uni3.pgm というファイルからPGM画像を読み込み,そのまま hoge.pgm という名前で出力するプログラムである. ex06image.c という名前でこれを作成し,コンパイルして実行してみよう.

  • myimage.c / myimage.h は書き換えてはならない
  • myimage.c では数学ライブラリに含まれる関数を用いているので,リンク時に -lm オプションをつける必要がある.
#include <stdio.h>
#include <stdlib.h>
#include "myimage.h"

int main(void)
{
  MyImage img;
  FILE *fp;

  fp = fopen("uni3.pgm", "r");
  if(fp == NULL){
    printf("ファイルを開けません\n");
    exit(EXIT_FAILURE);
  }
  readPGM(fp, &img);
  fclose(fp);

  fp = fopen("hoge.pgm", "w");
  if(fp == NULL){
    printf("ファイルを開けません\n");
    exit(EXIT_FAILURE);
  }
  writePGM(fp, &img);
  fclose(fp);

  return 0;
}

龍大計算機室のLinux環境では問題ないはずですが,他の環境の場合,上記のプログラムを正しく作成しても,実行時に Segmentation Falut や Bus Error になることがあります. そういう場合は,変数 img の宣言の頭に static をつけて

static MyImage img;

とするとよいです.どうしてこうするとよいのか知りたい人は,高橋に尋ねてください.

step2 [edit]

myimage.c を利用して,適当なPGM画像をファイルから読み込み,myimage.c で定義された関数を使って 「画素値反転」→「左右上下反転」→「うずまき」の順に処理して加工した画像を新たなPGM画像としてファイルに書き出すプログラムを作成しなさい.

  • myimage.c / myimage.h は書き換える必要はない
  • 「うずまき」だけ他の関数とは仕様が異なることに注意.
  • 「うずまき」の第2引数は,とりあえず \( \frac{\pi}{2} \) くらいの値を使い,その結果を見ていろいろ変えてみるとよいだろう.

課題D(TA) 次回の演習終了30分前 [edit]

郵便番号簿探索プログラムを作ろう. この課題には通常の課題2つ分の点数がつきます.

step1 [edit]

ディレクトリ /home/sample/takataka/aprog2014/ に,

  • zipdata100 100件分の郵便番号データから成るテキストファイル
  • zipsearch.o 探索の関数などをコンパイルして作られたオブジェクトファイル
  • zipsearch.h zipsearch.o用のヘッダファイル

という3つのファイルが置いてある. これらを自分のこの授業用のディレクトリにコピーし, zipsearch.o 以外のファイルの内容を less で確認しなさい(zipsearch.o はオブジェクトファイルなので less では普通の人は読めません.試してみると面白いかもしれませんが).

step2 [edit]

上記のファイルを利用して,zipdata100 に含まれるデータを読み込んで探索するプログラムを作りなさい.

  • mainを含むソースファイルの名前は ex06zs.c とすること
  • 課題Aの zssampleL や B と同様の動作をするように作ること(郵便番号の出力の形式に要注意).ただし,以下の2つの機能は実現しなくともよい(もちろんできる人は実現したらよい).
    • 探索回数の表示
    • データの配列中での位置の表示(zssampleL,Bでは [ ] で囲んでそれを表してます)
  • まずは線形探索するプログラムを作り,うまくいったら,二分探索の関数を使うように改造すること(二分探索するためにはデータをあらかじめ…

step3 [edit]

zipdata100 はデータが100件しかなくておもしろくないので,13万件弱のデータを含むファイルを使ってためそう. このファイルはサイズが大きい(約4MB)ので,各自のディレクトリにファイルをコピーするともったいない.次のように fopen するようにしたらよい.

fopen("/home/sample/takataka/aprog2014/zipdata", "r");

このように,fopenの引数には,ファイル名だけではなく,ディレクトリ名も含めたパスを指定することができる.

構造体の配列の大きさも大きくしなければならないことに気をつけよう. もしかすると,配列のサイズを大きくすると,プログラムが正しく書けているのに実行すると Bus Error となってしまうかもしれない. その場合は,配列の宣言の頭に static をつけて,

static ZIPDATA hoge[....];

のようにするとよい(どうしてこうするとよいか気になる人は,高橋に尋ねてください).

課題S(おまけ) [edit]

計算機室の環境に用意された ImageMagick という画像処理ツール群(displayコマンドもその一つ)の中に,animate というコマンドがある. カレントディレクトリに hoge000.pgm, hoge001.pgm, ..., hoge123.pgm のように連番のついた画像ファイルが存在していたとすると,

$ animate hoge*.pgm

と実行することで,これらのファイルを使ったアニメーションもどき(パラパラ漫画)を表示させることができる(メニューから表示速度を変えたりすることも可能).

そこで,適当な画像を使い,うずまき回転角を徐々に増やしながら uzumaki() を呼んで処理した画像を連番のついたファイル名で保存するプログラムを作成し,アニメーションさせてみよう. 1枚ずつ作るのではなく,プログラムを一度実行したら複数の画像が全部作成されるようにすること.


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