本講義では 2 通のレポートで評価します。 レポートは A4 縦の様式で PDF 形式で作成して下さい。 またプログラムは C 言語で作成しなさい。
課題1で使用した構造体 SEISEKI を前提とした、 次の構造体 NODE に関する関数を作成する。
#include "kadai1.h"
typedef struct node {
SEISEKI* seiseki;
struct node* left;
struct node* right;
} NODE;
ヘッダファイルなどはまとめて後ろに示してある。 また、kadai1.h も使用する。
なお、レポートにおいては、作成したプログラムの説明が必須であるが、課 題1で作成した関数に関しては説明する必要は無い。
以下のnodedata.c中のr1, r2, r3 が参照するデータ構造について、各 NODE型の中のデータの値を明示し、さらにポインターの接続を矢印で結んだ 図を作図しなさい。 なお、各変数の extern 宣言は kadai1.h, kadai2.h で宣言されている。
#include <stdlib.h>
#include "kadai2.h"
NODE n10={seisekidata21+2};
NODE n11={seisekidata21+1,&n10};
NODE n12={seisekidata21};
NODE r1={seisekidata21+3,&n11,&n12};
NODE n20={seisekidata22+6};
NODE n21={seisekidata22+4};
NODE n22={seisekidata22+5,&n20,&n21};
NODE n23={seisekidata22+2};
NODE n24={seisekidata22};
NODE n25={seisekidata22+1,&n23,&n24};
NODE r2={seisekidata22+3,&n22,&n25};
NODE n30={seisekidata22+5};
NODE n31={seisekidata22+4,&n30};
NODE n32={seisekidata22+6,NULL,&n31};
NODE n33={seisekidata22+1};
NODE n34={seisekidata22+2,NULL, &n33};
NODE n35={seisekidata22,&n34};
NODE r3={seisekidata22+3,&n32,&n35};
NODE* nodearray[]={&r1,&r2,&r3,NULL};
#include <stdlib.h>
#include "kadai1.h"
SEISEKI seisekidata21[]={{"21nc993",70},{"21nc990",90},{"21nc991",80},
{"21nc994",80},{NULL}};
SEISEKI seisekidata22[]={{"埼玉",7350},{"千葉",6259},{"東京",13921},
{"神奈川",9198},{"栃木",1934},{"茨城",2860},{"群馬",1942},{NULL}};
SEISEKI* seisekiarray2[]={seisekidata21, seisekidata22, NULL};
NODE 型のデータ同士で作った二分木の根を指すポインタ p を引数として、 木の持つSEISEKIデータを左から順に表示する関数 void nodeprint(NODE* p) を作成しなさい。 但し、nodeprint関数内で課題1で作成したseisekiprintを使用して良い。
そして、以下のプログラム ex22.c とnodedata.c seisekidata2.c と結合し、 出力を示しなさい。
#include <stdio.h>
#include <stdlib.h>
#include "kadai2.h"
int main(void){
NODE** p;
for(p=nodearray; *p!=NULL; p++){
nodeprint(*p);
printf("---\n");
}
return 0;
}
21nc991:80 21nc990:90 21nc994:80 21nc993:70 --- 群馬:1942 茨城:2860 栃木:1934 神奈川:9198 東京:13921 千葉:6259 埼玉:7350 --- 群馬:1942 茨城:2860 栃木:1934 神奈川:9198 東京:13921 千葉:6259 埼玉:7350 ---
2つの SEISEKI 型のポインタ、 p,q を受け取った時、以下の条件に従って値を返す
int seisekicomp(SEISEKI* p, SEISEKI* q)
を作成しなさい。
これと、以下のプログラム ex23.c と seisekidata.c を結合して実行し、出 力結果を示せ。
#include <stdio.h>
#include <stdlib.h>
#include "kadai2.h"
int main(void){
SEISEKI** p;
SEISEKI* q;
SEISEKI* r;
for(p=seisekiarray2; (*p)!=NULL; p++){
for(q=*p; q->id != NULL; q++){
printf("\t%s",q->id);
}
printf("\n");
for(q=*p; q->id != NULL; q++){
printf("%s",q->id);
for(r=*p; r->id != NULL; r++){
printf("\t%+d",seisekicomp(q,r));
}
printf("\n");
}
printf("\n---\n");
}
return 0;
}
21nc993 21nc990 21nc991 21nc994 21nc993 +0 -1 -1 -1 21nc990 +1 +0 +1 +1 21nc991 +1 -1 +0 +0 21nc994 +1 -1 +0 +0 --- 埼玉 千葉 東京 神奈川 栃木 茨城 群馬 埼玉 +0 +1 -1 -1 +1 +1 +1 千葉 -1 +0 -1 -1 +1 +1 +1 東京 +1 +1 +0 +1 +1 +1 +1 神奈川 +1 +1 -1 +0 +1 +1 +1 栃木 -1 -1 -1 -1 +0 -1 -1 茨城 -1 -1 -1 -1 +1 +0 +1 群馬 -1 -1 -1 -1 +1 -1 +0 ---
管理変数の番地とSEISEKIの番地を受け取り、順序木に格納する関数 NODE* nodeadd(NODE** root, SEISEKI* s) を作成しなさい。 但し、順序に関しては 問題2-3で作成した seisekicomp を使用しなさい。 また、戻り地は受け取ったSEISEKI の番地を含んでいる NODE 構造体の番 地を返しなさい。
これと、下記のテストプログラムex24.c, kadai2.h, nodeprint.c, seisekicomp.c, seisekiprint.c, seisekidata2.c を結合して実行し、 出力結果を示せ。
#include <stdio.h>
#include <stdlib.h>
#include "kadai2.h"
void nodedel(NODE* node){
if(node==NULL) return;
nodedel(node->left);
nodedel(node->right);
free(node);
}
int main(void){
SEISEKI** p;
SEISEKI* q;
NODE* root;
NODE* s;
for(p=seisekiarray2; *p!=NULL; p++){
root=NULL;
for(q=*p; q->id!=NULL; q++){
s=nodeadd(&root,q);
if(s==NULL){
fprintf(stderr,"メモリーエラー\n");
nodedel(root);
return 1;
}
seisekiprint(s->seiseki);
printf("\n");
}
printf("---\n");
nodeprint(root);
nodedel(root);
printf("------\n");
}
return 0;
}
21nc993:70 21nc990:90 21nc991:80 21nc994:80 --- 21nc993:70 21nc991:80 21nc994:80 21nc990:90 ------ 埼玉:7350 千葉:6259 東京:13921 神奈川:9198 栃木:1934 茨城:2860 群馬:1942 --- 栃木:1934 群馬:1942 茨城:2860 千葉:6259 埼玉:7350 神奈川:9198 東京:13921 ------
#include "kadai1.h"
typedef struct node {
SEISEKI* seiseki;
struct node* left;
struct node* right;
} NODE;
extern NODE* nodearray[];
extern SEISEKI seisekidata21[];
extern SEISEKI seisekidata22[];
extern SEISEKI* seisekiarray2[];
void nodeprint(NODE* p);
int seisekicomp(SEISEKI* a, SEISEKI* b);
NODE* nodeadd(NODE** root, SEISEKI* s);
void nodedel(NODE* node);
ex24.exe: ex24.o nodeprint.o seisekidata2.o seisekiprint.o nodeadd.o seisekicomp.o
$(CC) -o $@ $^
ex23.exe: ex23.o seisekicomp.o seisekidata2.o
$(CC) -o $@ $^
ex22.exe: ex22.o nodedata.o nodeprint.o seisekidata2.o seisekiprint.o
$(CC) -o $@ $^
ex22.o: kadai2.h
ex23.o: kadai2.h
ex24.o: kadai2.h
seisekidata2.o: kadai1.h
seisekiprint.o: kadai1.h
nodedata.o: kadai2.h
nodeprint.o: kadai2.h
seisekicomp.o: kadai2.h
nodeadd.o: kadai2.h
解答法として、分割コンパイルによる別ファイルにプログラムを書く方 法と、下記のテストプログラムに関数を追記する方法の二通りがあるが、 どちらでも良い。 プログラムの解説は、自分で作成した関数について行うこと。 こちらで提供したテストプログラムの説明は基本的には不要である。 但し、自分で作成した関数を説明するのに必要な内容には言及すること。
Makefile は使用してもしなくても良い。 また、問題そのものの改変は不合格であるが、プログラムを結合するためな どのやむを得ない必要な変更は許される。
なお、レポートは締め切り後も提出できます。 同じファイル名で複数のバージョンが存在できます。 締め切り内に採点可能なレポートがある場合は、最も締切に近いものだけを採 点します。 締め切り内に有効なレポートがない場合、最も新しいレポートを遅れレポー トとして減点の上採点します。
次の構造体の配列に関する関数を作成する。
typedef struct {
char* id;
int point;
} SEISEKI;
SEISEKI型の番地を受け取り、一行表示する関数
void seisekiprint(SEISEKI*)
を作成せよ。
但し、ファイル名を seisekiprint.c とする。
これと、下記のテストプログラム, kadai1.h, seisekidata.c を結合して実行し、出 力結果を示せ。
#include <stdio.h>
#include <stdlib.h>
#include "kadai1.h"
int main(void){
SEISEKI** p;
SEISEKI* q;
for(p=seisekiarray; *p!=NULL; p++){
for(q=*p; q->id!=NULL; q++){
seisekiprint(q);
printf("\n");
}
printf("\n");
}
return 0;
}
21nc990:90 21nc991:80 21nc993:70 21nc994:80 東京:13921 神奈川:9198 埼玉:7350 千葉:6259 茨城:2860 群馬:1942 栃木:1934
idがNULLとなっているデータで終端するSEISEKI型の配列の先頭番地を受け取り、
pointの平均値を返す
double seisekiave(SEISEKI* p)
を作成せよ。
この関数のファイル名を seisekiave.c とする。
これと、下記のテストプログラム, seisekidata.c, kadai1.h を結合して実行し、出 力結果を示せ。
#include <stdio.h>
#include <stdlib.h>
#include "kadai1.h"
int main(void){
SEISEKI** p;
for(p=seisekiarray; *p!=NULL; p++){
printf("%f\n",seisekiave(*p));
}
return 0;
}
80.000000 6209.142857
idがNULLとなっているデータで終端するSEISEKI型の配列の先頭番地を受け取り、
pointの標本分散を返す
double seisekivar(SEISEKI* p)
を作成せよ。
この関数のファイル名を seisekivar.c とする。
これと、下記のテストプログラム, seisekidata.c, kadai1.h を結合して実行し、出 力結果を示せ。
#include <stdio.h>
#include <stdlib.h>
#include "kadai1.h"
int main(void){
SEISEKI** p;
for(p=seisekiarray; *p!=NULL; p++){
printf("%f\n",seisekivar(*p));
}
return 0;
}
50.000000 16773165.836735
平均値、標本標準偏差、SEISEKI型の番地を受け取り、偏差値を返す関数
int seisekihensachi(double ave, double s, SEISEKI* p)
を作成せよ。
この関数のファイル名を seisekihensachi.c とする。
これと、下記のテストプログラム, seisekidata.c, seisekiprint.c, seisekiave.c, seisekivar.c, kadai1.h を結合して実行し、出 力結果を示せ。 なお、 sqrt を使用するために libm.a を結合する必要がある場合がある (Makefile では、コンパイルスイッチ -lm で対応)。
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "kadai1.h"
int main(void){
SEISEKI** p;
SEISEKI* q;
double ave;
double s;
for(p=seisekiarray; *p!=NULL; p++){
ave=seisekiave(*p);
s=sqrt(seisekivar(*p));
for(q=*p; q->id!=NULL; q++){
seisekiprint(q);
printf(":%d\n",seisekihensachi(ave,s,q));
}
printf("\n");
}
return 0;
}
21nc990:90:64 21nc991:80:50 21nc993:70:35 21nc994:80:50 東京:13921:68 神奈川:9198:57 埼玉:7350:52 千葉:6259:50 茨城:2860:41 群馬:1942:39 栃木:1934:39
typedef struct {
char* id;
int point;
} SEISEKI;
extern SEISEKI seisekidata1[];
extern SEISEKI seisekidata2[];
extern SEISEKI* seisekiarray[];
void seisekiprint(SEISEKI* p);
double seisekiave(SEISEKI* p);
double seisekivar(SEISEKI* p);
int seisekihensachi(double ave, double s, SEISEKI* p);
#include <stdlib.h>
#include "kadai1.h"
SEISEKI seisekidata1[]={{"21nc990",90},{"21nc991",80},{"21nc993",70},{"21nc994",80},{NULL}};
SEISEKI seisekidata2[]={{"東京",13921},{"神奈川",9198},{"埼玉",7350},{"千葉",6259},
{"茨城",2860},{"群馬",1942},{"栃木",1934},
{NULL}};
SEISEKI* seisekiarray[]={seisekidata1, seisekidata2, NULL};
$(CC) -o $@ $^
の $(CC) の前には TAB 記号が一つ
だけ入っていることに注意する。これが空白記号に置き換わっていると動作しない。
ex11.exe: ex11.o seisekidata.o seisekiprint.o
$(CC) -o $@ $^
ex12.exe: ex12.o seisekidata.o seisekiave.o
$(CC) -o $@ $^
ex13.exe: ex13.o seisekidata.o seisekivar.o
$(CC) -o $@ $^
ex14.exe: ex14.o seisekidata.o seisekiprint.o seisekiave.o seisekivar.o seisekihensachi.o
$(CC) -o $@ $^ -lm
ex11.o: kadai1.h
ex12.o: kadai1.h
ex13.o: kadai1.h
ex14.o: kadai1.h
seisekidata.o: kadai1.h
seisekiprint.o: kadai1.h
seisekiave.o: kadai1.h
seisekivar.o: kadai1.h
seisekihensachi.o: kadai1.h
個の点数データを とする。
なお、写したと思われるほど酷似したレポートが複数提出された場合、原著が どれかの調査を行わず、抽選で一通のレポートのみを評価 の対象とし、他は提出済みの不合格レポートとして再提出は課しません。 自分で意図せずに他人にコピーされてしまった場合も同様ですので、レポート の取り扱いについては十分に注意して下さい。