誰でも分かるC言語入門
■第4話:関数
(最終更新日:2024.04.16)
(絵が小さい場合はスマホを横に)
「関数を使って効率的にプログラミングしよう!」
今回は、C言語における関数の重要性と基本的な概念について学ぶ。
関数はプログラムを効率的に整理し、コードの再利用を可能にするための基本的なツールだ。
関数の定義、引数と戻り値の使い方、ローカル変数とグローバル変数の違い、そして再帰関数の利用方法に焦点を当てる。
これらの要素を理解することで、構造的で読みやすく、保守しやすいプログラムを作成することが可能になる。
このセッションを通じて、C言語の効果的な関数の書き方をマスターしましょう。
1.関数の定義と呼び出し
第4回「関数」では、C言語における関数の定義と呼び出しについて詳しく解説する。
関数はプログラムを小さなモジュールに分割し、コードの再利用を容易にするための非常に重要な概念だ。
■関数の定義
関数を定義するには、戻り値の型、関数名、引数リスト(パラメータ)を指定する。
関数本体は中括弧 {} で囲み、その中に処理を記述する。
下記の例では、addの前のintが戻り値の型(int型)、括弧内のa、bの前のintが引数の型(int型)で定義している。
実際、main関数内のadd関数の引数は、5と3を入れており、これにより、int型の戻り値8が結果として出力される。
関数の定義と使い方
■関数の呼び出し
関数が定義された後、プログラムのどこかでその関数を「呼び出す」ことができる。
関数を呼び出すには、関数名を使用し、括弧内に必要な引数を指定する。
関数が値を返す場合、その戻り値を変数に代入したり、他の式の一部として使用したりすることができる。
下記では、int型の変数sumに先ほどのadd関数の戻り値を代入している。
その値をprintfで結果として「Sum: 30」となるよう出力している。
関数の呼び出し例
■関数の利点
関数を使う利点としては、同じコードを繰り返し書く代わりに、関数を一度定義して何度も呼び出せる「再利用性」、
関数によってコードが小さな部分に分割されるため、プログラムの理解、開発、テストが容易になる「モジュール性」、
プログラムの特定の部分だけを変更することで、それを使っている全体の動作を変えられる「保守性」の向上が挙げられる。
2.引数と戻り値
次に引数と戻り値について詳しく解説する。
これらは関数がどのように外部のデータとやり取りするかを定義する。
関数の引数(パラメータ)は、関数が必要とする入力データを提供し、戻り値は関数が処理を終えた後に外部に出力するデータである。
■引数(パラメータ)
関数の引数は、関数が操作を実行するために外部から受け取る値だ。
引数は、関数定義の一部として宣言され、関数が呼び出される際に具体的な値が渡される。
C言語では、引数は値渡し(変数のコピーを作成)の方式で渡されることが一般的ですが、ポインタを通じてアドレス渡し(参照渡し)も可能になる。
ポインタについては、後の章で説明する。関数の使い方の項で説明した方法だと、直接引数に値を指定している。
■戻り値
戻り値は、関数がその計算の結果を呼び出し元に返すための値だ。
関数によっては結果を返す必要がない場合もあり、その場合、戻り値の型は voidとなる。
戻り値はreturnステートメントを使用して、関数から出力される。
引数と戻り値
■引数と戻り値の重要性
このように、引数を使うと何が良いかというと「汎用性」が上がることにある。
この場合、特定の値と値の掛け算だけでなく、引数を選択することで、様々な値の掛け算ができるようになる。
また、戻り値を使うことで、戻り値が正しい値を示しているかをテストすれば、その関数の妥当性を評価できる。
エラーの場所、もし戻り値が間違っていれば、エラーがその関数内にあるということが分かる。
つまり「エラーの局所化」ができる。
3.ローカル変数とグローバル変数
ここでは、ローカル変数とグローバル変数の違いについて解説する。 これらは関数内部および関数外部で使用される変数であり、それぞれ特定のスコープと寿命を持つ。
■ローカル変数
ローカル変数は関数内で宣言され、その関数の中でのみアクセス可能だ。
関数の実行が終了すると、ローカル変数はその寿命を終える。
これは関数内部の状態を他の部分のコードから隔離するのに役立ち、エラーやデータの不整合のリスクを減少させる。
下記のmyFunction内のlocalVar変数は、myFunction内だけで有効な変数となる。
特徴としては、関数が呼び出されるたびに新しいメモリ空間を割り当てる。関数が終了すると、localVarに割り当てた空間は破棄される。
また、初期化してないローカル変数は未定義の値になってしまうため、初期化することが重要だ。
ローカル変数の例
■グローバル変数
グローバル変数は関数の外部で宣言され、プログラムのどの部分からもアクセスできる。
これにより、異なる関数間でデータを共有することが可能になるが、不適切な使用はプログラムの状態を不安定にしたり、デバッグを困難にする。
グローバル変数はどこでも使えてしまうため、たくさんあると、既にどんな名前の変数を使ったか分からなくなるからだ。
値の変更もどこからでもできてしまう。ちなみに、グローバル変数は初期化されてない場合は、自動的に0(数値型)かNULL(ポインタ型)で初期化される。
プログラム実行開始時にメモリが割り当てられ、終了時に開放される。下記の例では、globalVarの値を最初に10にしているが、main関数内で20に変えている。
どちらの値をとるかは記述する場所による。
グローバル変数の例
グローバル変数のメリットとしては、複数の関数間でデータ共有できるということにある。 ただし、値の変更に気づかないこともあるので、不用意な使用は避けた方がよい。
4.再帰関数
再帰関数は、自身を呼び出す関数であり、反復処理を行う代わりに特定の問題を解決するために用いられる。
再帰的アプローチは、自然な方法で問題をより小さい問題に分割し、それらを解決することができる。
再帰は多くのアルゴリズム、特にデータ構造の操作や数学的問題解決において強力なツールとなる。
下記は、再起関数で階乗の計算を行った例だ。階乗の値が0になった際は、最後に1を掛けるものとしている。
このように、関数の中で自身の関数を呼び出すことで、上手く計算ができる。
この場合は5の階乗なので、5×4×3×2×1で、120が返り値になる。
階乗の計算以外にも、フィボナッチ数列や二分探索、マージソートなどもこの方法で計算できる。
再起関数、階乗の計算
5.まとめ
今回は、C言語における関数の基本、特に関数の定義、呼び出し、引数と戻り値の扱いに焦点を当てた。 関数はコードを再利用可能なモジュールに分割し、プログラムの構造を整理するために重要だ。 引数を通じて入力を受け取り、戻り値で処理結果を返すことで、関数は柔軟に動作する。 また、ローカル変数とグローバル変数の違いを学び、スコープと生存期間の理解を深めた。 再帰関数についても触れ、リカーシブコールによる解決手法を解説しました。 これらの知識は、効率的かつ効果的なプログラミングの基礎になるだろう。
▼参考図書、サイト
「かんたん C言語」 大川内 隆朗 技術評論社
「12歳からはじめる ゼロからのC言語ゲームプログラミング教室」 リブロワークス