Report#5 - 琉球大学 工学部 情報工学科

プログラミング
Report#5
提出日:
2008 年 6 月 20 日
所属:工学部情報工学科
学籍番号:
085735B
名前:
玉城幸一朗
次のプログラムは外部変数に定義され、初期化された 10 個の int 型データの平均を求
め、各データと平均との差を表示するプログラムである。 このプログラムを以下のよう
な関数の翻訳単位にファイルを分け、同様な動作をするプログラムを作成せよ。
型 関数名
float get_ave
void
print_data を使用する
※上の説明での「次のプログラム」というのは例のプログラムなのでここでは省略
average.c
#include<stdio.h>
float get_ave(void);
void print_data();
int score [10] = {3,5,8,9,10,6,7,9,8,3};
int i;
float ave;
int main() {
get_ave();
for(i=0; i<10; i++){
print_data();
}
return(0);
}
•このプログラムは 3•4 行目で関数を宣言している。
•順序としては、get_ave で平均値を求め、最後に print_data で 1 つのデータの平均値
との差を求めて表示する。
•ints core[10]には 0~9 の中に数字を代入する事が出来る。[10]と打って入るが、
1~10 までという意味ではない。こういう理由から for()の「i」の始まりは「0」であり、
「i」が「10」以上の値になるとループを終了する条件となっている。
•次に平均値を求めるプログラムである get_ave.c について
get_ave.c
#include<stdio.h>
extern int i;
extern int score[10];
extern float ave;
float get_ave() {
for(i=0; i<10; i++){
ave = ave + (float)score[i];
}
ave = ave / 10.0;
printf("ave = %3.1f\n",ave);
}
•extern というのは global(大域)であり、この変数はどの位置のプログラムでも同じ値
を扱う事が出来る。
•このプログラムは score にある値を ave に全て足し、その後平均値を求めるプログラム
である。
•プログラムの確認をしていると、変数を宣言するところで extern float ave の所の
extern は必要ないのではないかと思うので、後のオリジナルプログラムで確かめたいと
思う。
•続いて 1 つのデータの平均値との差を求めて表示する print_data.c について
print_data.c
#include<stdio.h>
extern int i;
extern int score[10];
extern float ave;
void print_data() {
float dif;
dif = score[i] - ave;
printf("score[%02d]=%2d Difference from average =
%4.1f\n",i,score[i],dif);
}
•変数を宣言するところで、extern を使い、float ave と宣言する事で先ほど
get_ave.c で出した値をそのまま使用する。
•このプログラムでは平均を出した後、score に入っている値 1 つと平均値との差を求め
るという事は小数点が出る可能性が高いので、float で変数 dif を宣言し、それに計算
結果を代入する。
これらの今は独立しているプログラム同士を、make コマンドで 1 つにまとめ実行する。
makefile.c
average: average.o get_ave.o print_data.o
gcc -o average average.o get_ave.o print_data.o
average.o: average.c
gcc -c average.c
get_ave.o: get_ave.c
gcc -c get_ave.c
print_data.o: print_data.c
gcc -c print_data.c
ここでエラーが発生した。
•エラーの出力
[tamaki-koichiro-no-macbook:~] e085735% make -f makefile
makefile:3: *** missing separator. Stop.
•直訳すると、分離が間違っているということだが、あまり意味が分からないので取り合
えず全角が混じっていなど調べたが、すべて半角で入力されているのでエラーの原因は他
にあると思い、よく考えると、先生がおっしゃっていた「Tab」の事を思い出し、
「Tab」を使用し間隔をあけるとコンパイルが出来た。
しっかり makefile.c が出来ているか実行してみた。
./average
[tamaki-koichiro-no-macbook:~] e085735%
ave = 6.8
score[00]= 3 Difference from average =
score[01]= 5 Difference from average =
score[02]= 8 Difference from average =
score[03]= 9 Difference from average =
score[04]=10 Difference from average =
score[05]= 6 Difference from average =
score[06]= 7 Difference from average =
score[07]= 9 Difference from average =
score[08]= 8 Difference from average =
score[09]= 3 Difference from average =
./average
-3.8
-1.8
1.2
2.2
3.2
-0.8
0.2
2.2
1.2
-3.8
例の通りの出力結果となった。
○この翻訳単位にファイル分けしたプログラムを利用し、オリジナルのプログラムを作成
する。
•1 つのデータの平均値との差を求めて表示するのに加え、計算結果の大きさによって A~D
まで範囲を決めておき、A~D を判定するプログラムを作成する。
新たに付け加えたプログラム
scope.c
#include<stdio.h>
extern float dif;
char c;
void get_sub(char c){
if(-0,9 <= dif <= 0.9 ){
c = 'A';
printf("scope = %c\n",c);}
else if(-1.9 <= dif <= -0.1 || 1.0 <= dif <= 1.9){
c = 'B';
printf("scope = %c\n",c);}
else if(-2.9 <= dif <= -2.0 || 2.0 <= dif <= 2.9 ){
c = 'C';
printf("scope = %c\n",c);}
else (-3.9 <= dif <= -3.0 || 3.0 <= dif <= 3.9 )
c = 'D';
printf("scope = %c\n",c);
}
•先ほどの print_data の結果によって、判定をするプログラムなのだがなぜかエラーが
出でしまう。
エラー
[tamaki-koichiro-no-macbook:~] e085735% gcc -c scope.c
scope.c: In function ‘get_sub’:
scope.c:17: error: syntax error before ‘c’
•おそらく char がいけないと思ったので、char を使わずにプログラムをくむとコンパイ
ルできた。
scope.c
#include<stdio.h>
extern float dif;
void scope(){
float
dif;
if(-0.9 <= dif <= 0.9) printf("scope = A\n");
else if(-1.9 <= dif <= 1.9) printf("scope = B\n");
else if(-2.9 <= dif <= 2.9 ) printf("scope = C\n");
else printf("scope = D\n");
}
•dif の値が-0.9~0.9 の間は「A」と判定され、-1.9~1.9 は「B」、-2.9~2.9 は
「C」、それ以外は「D」と判定されるプログラムを作った。
•このプログラムを for()の中の print_data の下に置く事で、毎回計算した値をそのま
ま判別し、これを繰り返す。
average.c
#include<stdio.h>
float get_ave(void);
void print_data();
char scope();
int score [10] = {3,5,8,9,10,6,7,9,8,3};
int i;
float ave;
int main() {
get_ave();
for(i=0; i<10; i++){
print_data();
scope();
}
return(0);
}
これで出力する。
makefile に新たに scope()を加え関連づけ、コパイルした。
./average
[tamaki-koichiro-no-macbook:~] e085735%
score[00]= 3 Difference from average =
scope = A
score[01]= 5 Difference from average =
scope = A
score[02]= 8 Difference from average =
scope = B
score[03]= 9 Difference from average =
scope = B
score[04]=10 Difference from average =
scope = B
score[05]= 6 Difference from average =
scope = B
score[06]= 7 Difference from average =
scope = B
score[07]= 9 Difference from average =
scope = B
./averageave = 6.8
-3.8
-1.8
1.2
2.2
3.2
-0.8
0.2
2.2
score[08]= 8
scope = B
score[09]= 3
scope = A
Difference from average =
1.2
Difference from average = -3.8
•なぜか正しく出力されなかった。
•理由が全くわかりません。
感想
makefile を用いた今回のプログラムは、とても難しかった。オリジナルプログラムを作
るところで判別が、正しく出力されなかったのが何故かわからなかったのが今回の大きな
反省点。
ただ、make を使ったプログラムの考え方や、関数をうまく用いてプログラムを作るの
はとても面白かった。…もっと早く取り組めばよかった。