2 部データ構造とアルゴリズムI レポート課題

本講義では 2 通のレポートで評価します。 レポートは A4 縦の様式で PDF 形式で作成して下さい。 またプログラムは C 言語で作成しなさい。

変更履歴

2026/5/21 18:10:00
課題1初出

課題1

レポート締切日: 2026年6月3日(水)23:59
提出先: BOX にファイル名を 学籍番号_1.pdfとして、 アップロードすること

解答法として、分割コンパイルによる別ファイルにプログラムを書く方 法と、下記のテストプログラムに関数を追記する方法の二通りがあるが、 どちらでも良い。 プログラムの解説は、自分で作成した関数について行うこと。 こちらで提供したテストプログラムの説明は基本的には不要である。 但し、自分で作成した関数を説明するのに必要な内容には言及すること。 また前問で作成した関数については自由に使用して良い。

問題とテストプログラムの改変は不合格である。 なお、こちらの提供したファイルやMakefile は使用してもしなくても良い。 また、プログラムを結合するためなどのやむを得ない必要な変更(include の代わりにプログラムを埋め込むなど)は許される。

問題の最後に、本課題で必要なヘッダファイル kadai1.h と Makefile を示す。また、 Visual Studio のソリューションを含む圧縮ファイルを置く。 課題で作成する関数は「関数名.c」というファイルに入れられる前提としている。

なお、課題1だけはレポートは締め切り後も提出できます。 同じファイル名で複数のバージョンが存在できます。 締め切り内に採点可能なレポートがある場合は、最も締切に近いものだけを採 点します。 締め切り内に有効なレポートがない場合、最も新しいレポートを遅れレポー トとして減点の上採点します。


kadai1.h には本課題に必要な宣言が含まれている。 まず、 構造体 SHOHIN は次のように定義されている。


typedef struct {
  int no;
  int shubetsu;
  int tanka;
  char* name;
} SHOHIN;

no は商品番号、 shubetsu は商品種別コード、 tanka は単価、name は商 品名を意味する。

また、構造体 URIAGE は次のように定義されている。


typedef struct {
  int no;
  int kosuu;
} URIAGE;

no は商品番号、 kosuu は個数を意味する。

またグローバル変数として、 商品種別コード別の税率が入っている配列 zeiritsu と 商品の配列 master (番兵として最後に no=0 となっている要素が含まれる) が次のように extern されている。


extern double zeiritsu[];
extern SHOHIN master[];

この他、課題で必要な、関数のプロトタイプ宣言が含まれている。 また、kadai1.c には zeiritsu, master の定義が含まれているため、 各問題で作成したプログラムを実行するには kadai1.c を結合する必要があ る。

問題1-1

構造体 SHOHIN の値を受け取り、 その商品種別コードから税率を得る double getzeiritsu(SHOHIN s) を getzeiritsu.cというファイルに作成せよ。

これと、下記のテストプログラム, kadai1.h, kadai1.c を結合して実行し、出 力結果を示せ。

kadai11.c


#include <stdio.h>
#include "kadai1.h"
int main(void){
  SHOHIN* p;
  for(p=master;p->no !=0; p++){
    printf("%2d:\t%-32s\t%4d円\t%2d%%\n",p->no, p->name, p->tanka,
	   (int)(getzeiritsu(*p)*100));
  }
  return 0;
}
出力例1-1
 1:	水性ボールペン           	 100円	10%
 2:	ノート                       	 200円	10%
11:	おにぎり                    	 100円	 8%
12:	サンドイッチ              	 200円	 8%

問題1-2

構造体URIAGEの の値を受け取り、その商品コードを master から検索して 、商品名、個数、税込価格、税率を表示し、税込み購入価格を返す double printuriage(URIAGE u) 関数を作成せよ。 この関数のファイル名を printuriage.c とする。

これと、下記のテストプログラム, kadai1.h, kadai1.c, getzeiritsu.cを 結合して実行し、出力結果を示せ。

kadai12.c


#include <stdio.h>
#include "kadai1.h"
int main(void){
  URIAGE list[] = {{1,1},{2,2},{11,3},{12,4},{0}};
  double keisan;
  double kakaku[]={110,440,324,864};
  double epsilon=0.01;
  int i;
  for(i=0;list[i].no !=0; i++){
    keisan= printuriage(list[i])-kakaku[i];
    if(keisan>-epsilon && keisan<epsilon){
      printf("Ok\n");
    }else{
      printf("NG\n");
    }
  }
  return 0;
}
出力例1-2
水性ボールペン           	x1	  110円 (税率10%)
Ok
ノート                       	x2	  440円 (税率10%)
Ok
おにぎり                    	x3	  324円 (税率8%)
Ok
サンドイッチ              	x4	  864円 (税率8%)
Ok

問題1-3

URIAGE の配列(ただし、最後に商品コード 0の番兵を含む)を受け取り、 それぞれの売上を表示し、最後に合計金額を表示し、合計金額を返す double printreceipt(URIAGE* u) 関数を作成せよ。

これと、下記のテストプログラム, kadai1.h, kadai1.c, getzeiritsu.c, printuriage.c を 結合して実行し、出力結果を示せ。

kadai13.c


#include <stdio.h>
#include "kadai1.h"
int main(void){
  URIAGE list[] = {{1,1},{2,2},{11,3},{12,4},{0}};
  double epsilon=0.01;
  double keisan;
  keisan = printreceipt(list)- 1738;
  if(keisan> -epsilon && keisan<epsilon){
    printf("Ok\n");
  }else{
    printf("NG\n");
  }
  zeiritsu[1]=0;
  keisan = printreceipt(list)- 1650;
  if(keisan>-epsilon && keisan<epsilon){
    printf("Ok\n");
  }else{
    printf("NG\n");
  }
  return 0;
}
出力例1-3
水性ボールペン           	x1	  110円 (税率10%)
ノート                       	x2	  440円 (税率10%)
おにぎり                    	x3	  324円 (税率8%)
サンドイッチ              	x4	  864円 (税率8%)
合計 1738.00円
Ok
水性ボールペン           	x1	  110円 (税率10%)
ノート                       	x2	  440円 (税率10%)
おにぎり                    	x3	  300円 (税率0%)
サンドイッチ              	x4	  800円 (税率0%)
合計 1650.00円
Ok

kadai1.h


typedef struct {
  int no;
  int shubetsu;
  int tanka;
  char* name;
} SHOHIN;
typedef struct {
  int no;
  int kosuu;
} URIAGE;
extern double zeiritsu[];
extern SHOHIN master[];
double getzeiritsu(SHOHIN s);
double printuriage(URIAGE u);
double printreceipt(URIAGE* u);

kadai1.c


#include "kadai1.h"
double zeiritsu[]={0.1,0.08};
SHOHIN master[] = {{1,0,100,"水性ボールペン"},
		   {2,0,200,"ノート"},
		   {11,1,100,"おにぎり"},
		   {12,1,200,"サンドイッチ"},
		   {0}};

Makefile

$(CC) -o $@ $^の $(CC) の前には TAB 記号が一つ だけ入っていることに注意する。これが空白記号に置き換わっていると動作しない。


kadai13.exe: kadai13.o kadai1.o getzeiritsu.o printuriage.o printreceipt.o
	$(CC) -o $@ $^
kadai12.exe: kadai12.o kadai1.o getzeiritsu.o printuriage.o
	$(CC) -o $@ $^
kadai11.exe: kadai11.o kadai1.o getzeiritsu.o
	$(CC) -o $@ $^
kadai11.o: kadai1.h
kadai12.o: kadai1.h
kadai13.o: kadai1.h
kadai1.o: kadai1.h
getzeiritsu.o: kadai1.h
printuriage.o: kadai1.h
printreceipt.o: kadai1.h

Visual Studio での開発法

下記の操作をしたものをalgo2026.zipとし てダウンロードできます。 ダウンロードしたzipファイルをすべて解凍して、中の sln ファイルをダブ ルクリックすると使用できます。

  1. プロジェクトを作成する時に、プロジェクト名を kadai11 とし、ソリュー ション名は別に与える(例えばalgo2026など)
  2. 日本語の設定として
    1. ツール→オプション
    2. 環境の中のドキュメントタブ
    3. 「特定のエンコードでファイルを保存する」をチェックし
    4. 「Unicode(UTF-8 署名付き)コードページ 65001」を選択する
  3. 以下をソリューションエクスプローラで実施する
  4. プロジェクト kadai11 には、ソースファイルとして、新しい項目に kadai11.c を入れる。
  5. プロジェクト kadai12, kadai13 をソリューションに追加す る。
  6. それぞれのプロジェクトに kadai12.c, kadai13.c をソー スファイルに入れる。
  7. ソリューションを右クリックして 「エクスプローラーでフォルダーを開く」
  8. kadai フォルダを新規に作成する
  9. kadai フォルダに kadai1.h, kadai1.cを入れる。 また、getzeiritsu.c, printuriage.c, printreceipt.c という名前の 空のファイルを、「新規作成→テキストドキュメントで作成して、名前の変更」 で作成する。これが終わったらエクスプローラーの画面を消して良い。
  10. 3つのプロジェクトそれぞれを右クリックして、プロパティを選ぶ。
    1. C/C++ の項目の最上段の「追加のインクルードディレクトリ」で <編集…>を選択し
    2. 入力欄に「$(SolutionDir)kadai」を入力し、Okを押す
    3. プロパティの Okを押す
  11. 3つのプロジェクトそれぞれで、 「ヘッダファイルを右 クリック→追加→既存のファイル」で kadai フォルダから kadai1.h を選び、 さらに、各プロジェクトで必要なファイルを「ソースファイルを右 クリック→追加→既存のファイル」 で追加する。
  12. 実行するプロジェクトを切り替えるには、実行したいプロジェクトを右クリックして「スタートアッププロジェクトに設定」を選ぶ

レポート作成上の注意

  1. レポートはグラフの表現など特殊な事情がない限り、必ず白黒で作成する こと。
  2. プログラミングのレポートでは必ずプログラムの説明をすること。その時 に、一行一行を日本語に直訳するのではなく、プログラムを機能毎に区分し、 機能の実現方法を説明すること。 プログラムに一行ずつコメントを入れてもプログラムの説明とは見なしません。
  3. 「問題を解きなさい」という問に対して「解きました。合ってました」は 正解ではありません。 「プログラムを作りなさい」という問題については、作成の手順の説明をする こと。 「テストしなさい」という問題についてはテストの手法、合否判定の基準、結 果の検討などを説明しなさい。
  4. プログラムが短くて説明がしづらい場合は、ポインタなどの関係を図示す るなどして工夫してください。
  5. 出力例は個々に異なりますので、手計算であらかじめ正しい値の求め方を 示し、値を提示してテストの合否を判定しなさい。
  6. レポートは手書きでも良いですが、プログラムの実行結果だけは必ずコン ピュータの出力の印刷(スクリーンショット)にして下さい。
  7. 考察は必ず書いて下さい。ネタがない人は以下を参考にして下さい。

なお、写したと思われるほど酷似したレポートが複数提出された場合、原著が どれかの調査を行わず、抽選で一通のレポートのみを評価 の対象とし、他は提出済みの不合格レポートとして再提出は課しません。 自分で意図せずに他人にコピーされてしまった場合も同様ですので、レポート の取り扱いについては十分に注意して下さい。


坂本直志 <sakamoto@c.dendai.ac.jp>
東京電機大学工学部情報通信工学科