STEP 8 - 定義関数
 │
 ├ 定義関数を作成する基本手順プロトタイプ宣言引数を持つ定義関数定義関数の基本的な記述戻り値を持つ定義関数再帰的な関数の呼び出し関数のポインタ呼び出し関数のポインタ配列
   └ ヘッダファイルの作成
猿でも解る C言語講座

Written by Yuki.
http://ftc.suki.net/
定義関数とは VBの自作関数の様なもの。定義関数もサブルーチンという。


<定義関数を作成する基本手順>  #include <stdio.h>  void func1(void); ' func1という定義関数の存在を宣言する。書かないと作った関数は使えない。  void main()  こういったプロトタイプ宣言は行末にセミコロンを付ける。  {    func1(); ' 定義関数を呼び出す。  }  void func1(void) ' "戻り値 関数名(引数)" で定義関数の定義になる。  {  戻り値が無ければ voidを指定。省略すると int型になる。    printf("こんにちは");    return; ' 定義関数の終わりを示す。  } ' これで "こんにちは" と表示する定義関数となる。  これでメインで呼ばれた定義関数で "こんにちは" と出力されるプログラムになる。  関数名の規則は変数名と同じで、標準関数と重複してはならない。関数名は大文字と小文字を区別する。  また、引数がなければ voidを指定する。
<プロトタイプ宣言>  ビルド(コンパイル)する時に、コンピュータにプロトタイプ宣言で  記述された定義関数が存在する事を知らせる。  #include <stdio.h>  void func1(void); ' 定義関数の存在を知らせる。宣言時はセミコロンを付ける。
<引数を持つ定義関数>  void func1(int a) ' 引数の型・定義関数内部で引数を格納する変数。  {    printf("%d\n",a);    return;  }  ・引数は 1つだけでなく、必要ならば複数定義できる。   void func2(int a,int b);   void func3(char *cp,int a);
<定義関数の基本的な記述>  戻り値の値 関数名(引数1の型 引数1,引数2の型 引数2,……) ' void func1(int a,int b)  { 戻り値なしなら↑    ↑引数なしなら void    関数で行う処理1;    関数で行う処理2;    return;  }  ・配列を引数にする時はポインタで指定する(文字列を引数にする時)。   void func1(int a,char *b); ' プロトタイプ宣言でもアスタリスクを付けておく。 ' メインで呼び出す時は、配列名のみを記述する。
<戻り値を持つ定義関数>  #include <stdio.h>  int max2(int,int);  void main()  {    int i;    i=max2(3,4); ' max2に値を代入する。その後、iにmax2の持つ値が入る。    printf("%d\n",i);  }  int max2(int a,nit b) ' 戻り値の型を指定。  {    if(a>=b) ' 値を判定。      return(a);    return(b); ' max2は 2つの引数のうち大きい値を返す。  }  定義関数自体が bという値を持っている。  ・printfで定義関数を指定すると、その関数の持つ値が出力される。   printf("%d\n",max2(2,5)); ' 実行されると戻り値の数値に置き換えられる。  上のプログラムで考えると、戻り値の 5に置き換えられる。  ※returnは関数の終わりではなく、mainに戻るという意味である。   return(戻り値);   return(1); ' 戻り値は 1。   return(a); ' 戻り値は aの格納している値。   return(a+1); ' aの格納している値+1。  ※returnはメインルーチンに戻る命令であり、同時に戻り値を指定する命令である。   サブルーチンが型を持っている場合は、returnの後に括弧を付けて戻り値を指定する。   だから、サブルーチンの型が voidの時には何も付かない事になる。   但し、関数の戻り値は一つしか指定できない。   int max2(int a,nit b)   {     if(a>=b){       return(a); ' returnがあると呼び出された所へ戻る。     }else{  その結果必然的に戻り値は一つになる。       return(b); ' elseならば、こちらの returnで、bの値が戻り     }  これ以下の文は実行されない。   }
<再帰的な関数の呼び出し>  #include <stdio.h>  void recurse(int);  void main()  {    recurse(0); ' メインから関数の呼び出し。recurseは再帰の意味。  }  void recurse(int i); ' 実際には関数の開始地点のアドレスを呼び出している。  {  そのアドレスの番号順に処理を行う。    if(i<3){ ' 呼び出しの際に 0を指定する事で iに 0が代入される。      recurse(i+1); ' 関数内でまたその関数を呼ぶ。これが再帰である。      printf("%d\n",i);    }    return;  }  @:メインから引数 0で呼び出される。  A:再帰して引数 1で呼び出される。  B:再帰して引数 2で呼び出される。  C:再帰して引数 3で呼び出される。    if文を実行せずに呼び出された場所へ戻る。この時Bへ戻る。  D:Bで呼び出しているので 2を表示。この後Aへ戻る。  E:Aで呼び出しているので 1を表示。@へ戻る。  F:@で呼び出しているので 0を表示。そして、メインへ戻る。  再帰では、それまでに繰り返してきた処理を、最後から順に出力していく。  最終的にはメインに戻り、処理が終了する。しかし実際にはこの方法は滅多に使わない。
<関数のポインタ呼び出し>  関数はビルドにより、マシン語に翻訳されてメモリに格納されている。関数が呼び出される時は、  関数の先頭アドレスが呼び出される。そのアドレスを、ポインタ変数などを用いて管理する。   ↓括弧で括る。  戻り値の型 (*ポインタ変数名)(引数の型);  ↑ポインタ変数に格納する  ↑引数が複数の場合はカンマで区切る。   関数の戻り値の型。  (使用例)   int型の引数を 2つ持ち、int型の戻り値を返す関数を格納するポインタ。   int (*p)(int,int);  ※格納する関数の戻り値の型、引数と個数。これらは必ず一致していなくてはならない。   int func(int,int);   p=func;   ' 関数名のみを書く事により、その関数の先頭アドレスを表す。
<関数のポインタ配列>  考え方は変数を使用したポインタ配列と同じである。  戻り値の型 (*ポインタ変数名[要素数])(引数の型);  (使用例)   戻り値の型と引数の型・個数が同じ関数が 3つあるケース。   int func1(int);   int func2(int);   int func3(int); ' 一つ一つがサブルーチン。   int (*p[3])(int)={func1,func2,func3}; ' 中括弧内のそれぞれが pの要素になる。   2つの数値の計算方法を指定する。   #include <stdio.h>   int add(int,int);   int sub(int,int); ' プロトタイプ宣言。   int (*p[2])(int,int)={add,sub} ' ポインタ配列に 2つのサブルーチン(の要素の型)。   void main()   {     int i,j,op,res; ' i,jは数値入力用、opはポインタ配列の添え字、     scanf("%d",&i);  resはポインタ配列の戻り値を格納する為のもの。     scanf("%d",&j);     do{       scanf("%d",&op);     }while(op<0 || op>1); ' opに 0より下、又は 1より上が入力されている間、繰り返す。     res=(*p[op])(i,j); ' ポインタ配列の 0、又は 1に i,j の値を。     printf("%d\n",res); ' printfで resに入った戻り値を呼ぶ。   }   int add(int a,int b) ' a=i,b=j   { return(a+b); } ' 宣言の時点で addが 0、subが 1である。 ' opに 0が入れば、加算するサブルーチンを、   int sub(int a,int b) ' 1なら減算するサブルーチンを実行する。   { return(a-b); } ' 計算結果が戻り値として resに入り、出力される。   この様に、ポインタ配列でサブルーチンを管理する事で、   任意の計算方法を選択したり、処理の仕方の分岐等をさせる事ができる。  ※関数を配列にする時には、要素となる定義関数の引数は全て同じでなければならない。   上の例のように、addと subの引数が同じでない時、例えば要素の 1つが intでなかったり、   戻り値の型が違ったりするとエラーになる。   要素の型は、ポインタ配列の宣言の時に書かれた要素と同じである必要がある。  ・ヘッダファイルの作成   @:「ファイル」→「新規作成」の順にクリック。   A:一番上の「C/C++ヘッダファイル」の項目をクリック。ファイル名を付けて、OKを押す。   B:クラスの下に (ファイル名).h のヘッダファイルが作成される。     ヘッダファイルには定義関数等を記述しておく。
← ← Back to BeforeStep Go to NextStep → →