f(x) = 3x2 - 4x + 7
この関数 f(x)は x の値を具体的に入れてあげれば関数の答えも決まります。x = 10 とすれば、
f(10) = 267
となりますね。C言語の関数も同じような働きをします。関数はある値を与える(入力)と何らかの処理をして(機能)結果を関数の値(出力)として返すわけです。C言語の関数には値を返さない関数もあります。こういう関数は関数の処理自体に意味があるのでとりわけ答えを返す必要がないのです。
さて、もし f (x) = 3x2 - 4x + 7 だと知っていて f(x) に xを代入すれば自動的に答えが求められるのであれば f(x) がどうやって計算をしているかという過程は知らなくても使う側からみれば問題ないですよね?つまり、その関数の働きが分かっていれば関数を「ブラックボックス(*)」として扱い内部のことまでは気にしなくてもいいのです。大胆な例を挙げるとすれば、普段パソコンを使っているときにその内部でパーツがどんな風に動作しているかいちいち考えなくても全然問題なく使っていられますよね?それと同じなのです。
このように関数はブラックボックスと考えることができることが分かったと思うのですが、ブラックボックスだとどのようなメリットがあるのでしょうか?例えば・・・
> プログラムが分かりやすくなる
> 複数人で分担してプログラムできるようになる
> 一度作ったものを再利用しやすくなる
など、効果は絶大です。中でも再利用できるという点はプログラマが受ける恩恵はとても大きいのです。この講座の最初にLSI-Cというコンパイラを入手したと思いますが、このコンパイラについてくるものに標準ライブラリというものがあります。これは基本的な入出力や文字列操作などを簡単に使えるようにした関数の集まりなのです。今までのサンプルで画面に文字を表示しましたが、これも標準ライブラリの中の printf という関数を使って表示していたのです。
標準ライブラリ以外にも様々な人たちがグラフィックスや複雑な統計処理などのライブラリを提供しているので簡単に機能を拡張することが可能です。
このようにC言語をプログラムするということはさまざまな関数のコンビネーションで機能を作り出すことなのです。関数がどんなものか分かってもらえたと思うのでその中身を見ていきましょう。
[ 例 ] 関数を使って3*x2 - 4*x +7 を計算する例 ex6-1.c
2.関数の定義
型宣言子 関数名 (仮引数の並び) { 関数内部の変数の宣言; 実行文; ・・・・ } |
関数を定義するときには読みやすいプログラムにする努力をします。関数名は関数の働きが分かるような適切な名前にします(これについては後述するかも知れません)。コメントで関数の働きを説明しておくことも有効な手段です。引数や戻り値(=関数の返す値)なども説明しておくのがいいでしょう。これらの関数を説明するコメント文を関数ヘッダと読んだりもします。関数ヘッダの記述スタイルは自由ですが、自分なりに工夫して分かりやすいスタイルに統一するようにしましょう。
[ 例 ] 関数ヘッダの例
/* -------------------------------------------------
関数名 : funcx
機能 : 3^x - 4 * x + 7 を計算する
引数 : int x >> 入力データ
戻り値 : int y >> 計算結果
--------------------------------------------------- */
int funcx (int x)
{
・・・・
コメントについて
【正しいコメントの例】
int val; /* 変数の宣言(行の途中からでも記述できる)*/
/* コメントの例
このように複数行にわたっていても問題ない。
val = 5; ← 正しい文でもコメント中の文はコンパイルされない(エラーではない) */
【間違ったコメントの例】
/* 良くないコメントの例
/* 入れ子の場合だとこの部分でコメントが終わりだと認識されてしまい → */
*/ ←この部分でエラーになる
もう一つ // というのがあってこれはその行の // 以降をコメントと見なします。しかし、// をコメントとして認識しないコンパイラもあります。(LSI-Cも認識しない)
3.関数の呼び出し
関数名 (実引数の並び) |
一般的に関数を記述する際にはプロトタイプ宣言と呼ばれるものします。コンパイルをするときにコンパイラはファイルの先頭から順番にコンパイルします。この時に関数の定義が呼び出しよりも先にないと関数を見つけられずコンパイルエラーとなります。これに従うと関数を使ったプログラムはこんな感じになります。
しかし、関数本体はあくまでも「ブラックボックス」です。ブラックボックスがいきなりでてきてしまうとプログラムとして分かりづらくなります。そこで、関数の呼び出し側よりも先に関数の型と引数の型宣言だけあらかじめ行っておくのです。これが関数のプロトタイプ宣言なのです。
プロトタイプ宣言の仮引数では引数名を省略してデータ型の並びだけにしても構いません。注意する点はプロトタイプ宣言は文なので、最後に「 ; 」を忘れないことです。