これまでの学習で,諸君は知らない間に関数を使っていた.おまじないと言っていたもの の一部はmain()関数と呼ばれるものである.いままでのプログラムを思い出してほ しい.必ず,mainとか言うものを書いていたはずである.
main()関数にかぎらず,これから学習する関数は同じような構造である. main()関数の構造を図1に示す.それぞれの役割は,以下の とおりである.
このmain()関数の例でも分かるように,関数での処理の内容はブロック--中括弧 { }で囲まれた部分--中に書かれなくてはならない.今まで,学習してきたプロ グラムでは,main関数のみがあり,その中に実行文が書かれていたはずである.プ ログラムでは,このブロックを処理のひとかたまりと考える.
main関数は特別で,C言語のプログラムには,必ず1個必要で,そこから実行される ことになっている.
このプログラムでは,main関数とbiggerと言う関数が使われている. main関数の構造については,先ほど述べたとおりである.biggerの方は,次の ようになっている.
このリスト1の動作の内容を,図2のフローチャー トに示す.動作は単純なので,すぐに理解できるであろう.関数を使って,大きい方の値 を調べ,表示している.
数学の関数とほとんど同じような動作をしていることが分かるだろう.数学では変数を与
えて,関数値が求まる.C言語では,変数に代わり引数が与えられ,戻り値がも求まるわ
けである.
1 #include <stdio.h> 2 3 double bigger(double a, double b); /* プロトタイプ宣言 */ 4 5 /*=====================================================================*/ 6 /* メイン関数 */ 7 /*=====================================================================*/ 8 int main(void){ 9 double x, y, z; 10 11 x=2.5; 12 y=3.1415; 13 14 z=bigger(x, y); 15 16 printf("大きい方は、%fです。\n", z); 17 18 return 0; 19 } 20 21 /*=====================================================================*/ 22 /* 大きい方を探す関数 */ 23 /*=====================================================================*/ 24 double bigger(double a, double b){ 25 double big; 26 27 if(a<b){ 28 big = b; 29 }else{ 30 big = a; 31 } 32 33 return big; 34 35 }
もう一つ,長いプログラムの問題は,処理が分かりにくい点である.例えば, windows2000だとソースプログラムは大体4000万行だと言われている.この場合,それぞ れの実行文の役割など分からない.コンピューターは大量のトランジスターからできてい るが,それぞれの役割が分からないのと同じである.このように大量の部品(実行文)から 構成されるコンピューター(プログラム)の動作を考える際に重要なことは,モジュール 3に 分解することである.そうすると,動作の内容が分かるようになる.長いプログラムを作 る場合も同じで,機能単位(モジュール)に分け,分かりやすくすることが重要である.C 言語では関数を使い,機能単位にプログラムを分割する.
まとめると,関数の役割は
このプログラムでは,乱数を使っている.乱数の発生方法については,このプリントの付
録(以降)に書いてある.又教科書のp.449のsrand関数の説明の
部分にも書いてある.
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <time.h> 4 5 int main(void){ 6 int a[10], b[100], max_a, max_b, i; 7 8 srand((unsigned int)time(NULL)); /* 起動毎に異なる乱数発生のため */ 9 10 for(i=0; i<10; i++) a[i]=rand(); /* 配列 a[] の値設定 */ 11 for(i=0; i<100; i++) b[i]=rand(); /* 配列 b[] の値設定 */ 12 13 /* ---- 配列 a[] の最大値検索 ----- */ 14 max_a=a[0]; 15 for(i=1; i<10; i++){ 16 if(max_a<a[i]) max_a=a[i]; 17 } 18 19 /* ---- 配列 b[] の最大値検索 ----- */ 20 max_b=b[0]; 21 for(i=1; i<100; i++){ 22 if(max_b<b[i]) max_b=b[i]; 23 } 24 25 printf("max a=%d\n",max_a); /* 最大値印刷 */ 26 printf("max b=%d\n",max_b); 27 28 return 0; 29 }
リスト2をよく見ると,最大値を求める部分はほとんど同じ
である.そこで,それを一つの関数にまとめることを考える.リスト
3のようにすれば良い.これで,プログラムがすっきりした.こうす
ると,最大値を求めるアルゴリズムを変えたい場合でもプログラムの変更が容易である.
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <time.h> 4 5 int find_max(int n, int ix[]); /* プロトタイプ宣言 */ 6 7 /*=========================================================================*/ 8 /* main 関数 */ 9 /*=========================================================================*/ 10 int main(void){ 11 int a[10], b[100], max_a, max_b, i; 12 13 srand((unsigned int)time(NULL)); /* 起動毎に異なる乱数発生のため */ 14 15 for(i=0; i<10; i++) a[i]=rand(); /* 配列 a[] の値設定 */ 16 for(i=0; i<100; i++) b[i]=rand(); /* 配列 b[] の値設定 */ 17 18 max_a=find_max(10, a); 19 max_b=find_max(100,b); 20 21 printf("max a=%d\n",max_a); /* 最大値印刷 */ 22 printf("max b=%d\n",max_b); 23 24 return 0; 25 } 26 27 /*=========================================================================*/ 28 /* 最大値探索の関数 */ 29 /*=========================================================================*/ 30 int find_max(int n, int ix[]){ 31 int i, max; 32 33 /* ---- 配列 a[] の最大値検索 ----- */ 34 max=ix[0]; 35 for(i=1; i<n; i++){ 36 if(max<ix[i]) max=ix[i]; 37 } 38 39 return max; 40 }
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <time.h> 4 5 /* ---- プロトタイプ宣言 ----- */ 6 void make_data(int nx, int ix[], int ny, int iy[]); 7 int find_max(int n, int ix[]); 8 void print_results(int a, int b); 9 10 /*=========================================================================*/ 11 /* main 関数 */ 12 /*=========================================================================*/ 13 int main(void){ 14 int a[10], b[100], max_a, max_b; 15 16 17 make_data(10, a, 100, b); /* 乱数データ作成 */ 18 19 max_a=find_max(10, a); /* 最大値検索 */ 20 max_b=find_max(100,b); 21 22 print_results(max_a, max_b); /* 最大値印刷 */ 23 24 return 0; 25 } 26 27 28 /*=========================================================================*/ 29 /* データ作成 */ 30 /*=========================================================================*/ 31 void make_data(int nx, int ix[], int ny, int iy[]){ 32 int i; 33 34 srand((unsigned int)time(NULL)); /* 起動毎に異なる乱数発生のため */ 35 36 for(i=0; i<nx; i++) ix[i]=rand(); 37 for(i=0; i<ny; i++) iy[i]=rand(); 38 39 } 40 41 42 /*=========================================================================*/ 43 /* 最大値探索の関数 */ 44 /*=========================================================================*/ 45 int find_max(int n, int ix[]){ 46 int i, max; 47 48 /* ---- 配列 a[] の最大値検索 ----- */ 49 max=ix[0]; 50 for(i=1; i<n; i++){ 51 if(max<ix[i]) max=ix[i]; 52 } 53 54 return max; 55 } 56 57 58 /*=========================================================================*/ 59 /* 結果の印刷 */ 60 /*=========================================================================*/ 61 void print_results(int a, int b){ 62 63 printf("max a=%d\n",a); 64 printf("max b=%d\n",b); 65 66 }