本講義では 2 通のレポートで評価します。 レポートは A4 の紙を縦に使い、適宜表紙を付けて提出すること。 またプログラムは C 言語で作成しなさい。
課題2-1の実行例が間違っていましたので、訂正しました(2015/7/13)
なお、遅れレポートは原則受けとりません。
時間を表わすため、構造体を次のように定義した。
typedef struct {
int hour;
int minute;
int second;
} JIKAN;
なお、jikan.h や、他に必要な関数は後述する。
時間の大小関係を比較する int compare(JIKAN* a, JIKAN* b) を作成しなさい。 ただし、これは a,b とも JIKAN 型の変数を指すポインターで、 *a < *b の時は負の整数、 *a == *b の時は0、 *a > *b の時は正の整数を返しなさい。
なお、以下のプログラムと結合してテストを行い、実行結果を示しなさい。
#include <stdio.h>
#include "jikan.h"
int main(void){
JIKAN jikan[]={{1,2,3},{1,2,2},{1,4,3},{2,2,3}};
int arraysize = sizeof(jikan) / sizeof(JIKAN);
int i;
int j;
for(j=0;j<arraysize;j++){
printf("\t");
print(jikan+j);
}
printf("\n");
for(i=0;i<arraysize;i++){
print(jikan+i);
for(j=0;j<arraysize;j++){
printf("\t%d",compare(jikan+i,jikan+j));
}
printf("\n");
}
return 0;
}
1:2:3 1:2:2 1:4:3 2:2:3 1:2:3 0 1 -2 -1 1:2:2 -1 0 -2 -1 1:4:3 2 2 0 -1 2:2:3 1 1 1 0
1:2:3 1:2:2 1:4:3 2:2:3 1:2:3 0 -1 2 1 1:2:2 1 0 2 1 1:4:3 -2 -2 0 1 2:2:3 -1 -1 -1 0
なお、compare 関数では返す整数の符号が一致していれば良く、実行例で示し た整数値と一致する必要はない。
JIKAN* を含む線形リストを作成するために、次の構造体を定義した。
typedef struct list {
JIKAN* jikan;
struct list* next;
}LIST;
この構造体で作られた線形リストのJIKANを \t で区切って表示する関数 void printlist(LIST* l) を作成しなさい。 但し、後に示す void print(JIKAN* j) を使用してよい。 また、先頭に \t が来ても構わない(以下実行例では先頭に\tが来ている)。 そして、以下のテストプログラムと結合して、テスト結果を示しなさい。
#include <stdio.h>
#include <stdlib.h>
#include "jikan.h"
int main(void){
JIKAN jikan[]={{1,2,3},{1,2,2},{1,4,3},{2,2,3}};
LIST lnull={NULL,NULL};
LIST l3={jikan+3,&lnull};
LIST l2={jikan+2,&l3};
LIST l1={jikan+1,&l2};
LIST l0={jikan,&l1};
printlist(&l0);
printf("\n");
printlist(&l1);
printf("\n");
printlist(&l2);
printf("\n");
printlist(&l3);
printf("\n");
printlist(&lnull);
printf("\n");
return 0;
}
1:2:3 1:2:2 1:4:3 2:2:3 1:2:2 1:4:3 2:2:3 1:4:3 2:2:3 2:2:3
JIKAN のポインター now と JIKAN の線形リストの先頭を指すポインターから、 与えた時間 *now より長い時間のみからなる新たな線形リストを返す関数 LIST* longtimelist(JIKAN* now, LIST* l) を作成しなさい。 但し、後に示す関数を使用してよい。 そして、以下のテストプログラムと結合して、テスト結果を示しなさい。
#include <stdio.h>
#include <stdlib.h>
#include "jikan.h"
int main(void){
int i;
JIKAN jikan[]={{1,2,3},{1,2,2},{1,4,3},{2,2,3}};
int arraysize = sizeof(jikan) / sizeof(JIKAN);
LIST lnull={NULL,NULL};
LIST l3={jikan+3,&lnull};
LIST l2={jikan+2,&l3};
LIST l1={jikan+1,&l2};
LIST l0={jikan,&l1};
LIST* p;
for(i=0; i<arraysize; i++){
print(jikan+i);
printf("\t<");
p=longtimelist(jikan+i,&l0);
printlist(p);
printf("\n");
freelist(p);
}
return 0;
}
1:2:3 < 1:4:3 2:2:3 1:2:2 < 1:2:3 1:4:3 2:2:3 1:4:3 < 2:2:3 2:2:3 <
typedef struct {
int hour;
int minute;
int second;
} JIKAN;
typedef struct list {
JIKAN* jikan;
struct list* next;
}LIST;
void print(JIKAN* v);
void add(JIKAN* v,JIKAN* w);
void normalize(JIKAN* v);
int compare(JIKAN* a, JIKAN* b);
void printlist(LIST* l);
JIKAN* dupjikan(JIKAN* j);
LIST* newlist();
void freelist(LIST* l);
LIST* duplist(LIST* l);
LIST* longtimelist(JIKAN* now, LIST* l);
#include <stdio.h>
#include <stdlib.h>
#include "jikan.h"
void print(JIKAN* j){
printf("%d:%d:%d",j->hour,j->minute,j->second);
}
JIKAN* dupjikan(JIKAN* j){
JIKAN* result = malloc(sizeof(JIKAN));
if(result !=NULL){
result->hour = j->hour;
result->minute = j->minute;
result->second = j->second;
}
return result;
}
LIST* newlist(){
LIST* result = malloc(sizeof(LIST));
if(result!=NULL){
result->jikan= NULL;
result->next = NULL;
}
return result;
}
void freelist(LIST* l){
if(l->next != NULL){
freelist(l->next);
}
if(l->jikan != NULL){
free(l->jikan);
}
free(l);
}
LIST* duplist(LIST* l){
LIST* result=newlist();
LIST* p;
if(result==NULL) return NULL;
for(p=result; l->next!=NULL; l = l->next){
if((p->jikan = dupjikan(l->jikan))==NULL){
freelist(result);
return NULL;
}
if((p->next = newlist())==NULL){
freelist(result);
return NULL;
}
p = p->next;
}
return result;
}
レポートには自ら作成した関数の説明をし、テストプログラムと結合して実行 した結果を載せること。
解答法として、分割コンパイルによる別ファイルにプログラムを書く方 法と、下記のテストプログラムに関数を追記する方法の二通りがあるがどちら でも良い。 プログラムの解説は、自分で作成した関数について行うこと。 こちらで提供したテストプログラムの説明は基本的には不要である。 但し、自分で作成した関数を説明するのに必要な内容には言及すること。
なお、遅れレポートは教員に直接提出してください。 遅れた方が有利にならない範囲内で採点します。
時間を表わすため、構造体を次のように定義した。
typedef struct {
int hour;
int minute;
int second;
} JIKAN;
なお、jikan.h は後述する。
JIKAN 型の変数のポインターを受け取り、「hour:minute:second」の書式で表示する void print(JIKAN* j) 関数を作りなさい。
そして、テストプログラム1と結合して正しく動作していることを確認しなさい。
#include <stdio.h>
#include "jikan.h"
int main(void){
JIKAN j[]={{12,34,56},{1,60,60},{100,58,120},{-1,-1,-1}};
JIKAN* p;
for(p=j; p->hour!=-1; p++){
print(p);
printf("\n");
}
return 0;
}
12:34:56 1:60:60 100:58:120
JIKAN型の変数のポインターを二つ受け取り、1番目の変数に2番目の変数の値を 足し込む void add(JIKAN* v, JIKAN* w) 関数を作りなさい。
そして、下記のテストプログラム2と結合して、正しく動作することを確かめなさい。
#include <stdio.h>
#include <stdlib.h>
#include "jikan.h"
int main(void){
JIKAN j[]={{12,34,56},{1,60,60},{100,58,120},{-1,-1,-1}};
JIKAN* p;
JIKAN q={5,6,7};
for(p=j; p->hour!=-1; p++){
print(p);
printf(" + ");
print(&q);
printf(" = ");
add(p,&q);
print(p);
printf("\n");
}
return 0;
}
12:34:56 + 5:6:7 = 17:40:63 1:60:60 + 5:6:7 = 6:66:67 100:58:120 + 5:6:7 = 105:64:127
JIKAN型の変数のポインターを受け取り、秒、分に関して60以上だった時にそれぞれ分、時に換算して、秒、分を正規化させる void normalize(JIKAN* v) 関数を作りなさい。
そして、下記のテストプログラム3と結合して、正しく動作することを確かめなさい。
#include <stdio.h>
#include <stdlib.h>
#include "jikan.h"
int main(void){
JIKAN j[] = {{12,34,56},{1,60,60},{100,58,120},{-1,-1,1}};
JIKAN* p;
JIKAN q = {5,6,7};
for(p=j; p->hour!=-1; p++){
print(p);
printf(" + ");
print(&q);
printf(" = ");
add(p,&q);
print(p);
normalize(p);
printf(" -> ");
print(p);
printf("\n");
}
return 0;
}
12:34:56 + 5:6:7 = 17:40:63 -> 17:41:3 1:60:60 + 5:6:7 = 6:66:67 -> 7:7:7 100:58:120 + 5:6:7 = 105:64:127 -> 106:6:7
jikan.h は次のように上記の構造体と作るべき関数のすべてのプロトタイプ 宣言が入っているファイルとする。
typedef struct {
int hour;
int minute;
int second;
} JIKAN;
void print(JIKAN* v);
void add(JIKAN* v,JIKAN* w);
void normalize(JIKAN* v);