C言語の関数の定義方法を解説します【function】

598, 2022-12-07

目次

C言語の関数の定義方法は?

C言語の関数の定義は↓のように行います。

#include <stdio.h>

void func1(void) {
    puts("Hello, World!");
}

int mul(int a, int b) {
    return a * b;
}

C言語の関数はC言語プログラムでは非常によく使う機能です。
この関数を知っておかないと大規模プログラムなども作れません。
ですのでぜひとも押さえておきたいものです。

C言語は強力な型機能があります。
関数も例外ではなく、C言語で関数を扱うには型についての意識も必要になってきます。

この記事ではC言語の関数の定義方法について解説します。

関数の定義方法

C言語では関数の定義は↓のフォーマットに従って行います。

返り値の型 関数名(引数, 引数, ...) {
    関数の中身
}

関数は返り値を返します。
ですので返り値の型を関数名の前に指定します。
これは「int」とか「float」とかになります。

関数名を書いてそのあとのカッコの中に引数を書きます。
引数は「型名 引数名」の形式で書きます。
引数はカンマで区切ると複数指定できます。

関数の定義側の引数を仮引数と言います。
実際の関数呼び出し側の引数は実引数と言います。
引数はこのように区別して呼称されています。

実際に関数を定義したサンプル

実際に関数の定義のサンプルをいくつか見てみます。

#include <stdio.h>

void func1(void) {
    puts("Hello, World!");
}

int mul(int a, int b) {
    return a * b;
}

double get_weight(void) {
    return 60.23;
}

const char *get_name(void) {
    return "Taro";
}

void store_pi(double *p) {
    *p = 3.14;
}

これらの関数はどれもC言語で有効な関数です。

func1()は「Hello, World!」を画面に出力します。
標準のputs()関数を使っています。

mul()は引数abを掛け算しその結果をintで返す関数です。
get_weight()は返り値で実数を返します。

get_name()は文字列定数を返します。
store_pi()は引数のポインタに3.14を格納する関数です。

整数と関数

整数と絡めてC言語の関数を定義してみます。
C言語の整数の方は代表的なものはintshort, longなどがあります。
これらの型はすべて関数の返り値の型、そして引数の型に使うことができます。

では試しにlong型を使ってget_squre()という関数を定義してみましょう。

long get_square(long w, long h) {
    return w * h;
}

この関数はたとえば↓のように使うことができます。

    long size = get_square(100, 50);
    printf("%ld\n", size);  // 5000

C言語のlong型のサイズの値の範囲は

  • -2,147,483,648 ~ 2,147,483,647

の範囲になります。
これだけあれば四角形の面積を求めるには十分ですね。

実数と関数

では次に実数と関数を絡めて見ていきたいと思います。
角度をラディアンに変換する関数を定義してみましょう。

角度は度数法の単位でラディアンは弧度法の単位になります。
つまり単位変換ですね。
この単位変換は三角関数を使う時などによく使われます。

#include <math.h>

double deg_to_rad(double deg) {
    return deg * M_PI / 180.0;
}

弧度法で言うM_PIはちょうど度数法で言う180度になります。
ですのでM_PIを180で割ると一度についてのラディアンが求まります。
そのラディアンをdegにかければdegに含まれるラディアンの量がわかるという寸法です。

この関数を実行すると↓のような結果になります。

    printf("%lf\n", deg_to_rad(0));  // 0.000000
    printf("%lf\n", deg_to_rad(45));  // 0.785398
    printf("%lf\n", deg_to_rad(90));  // 1.570796

文字列と関数

次に文字列と関数を絡めて見ていきましょう。

文字列定数はプログラムのテキストセグメントという領域にデータが確保されています。
これは静的なデータでプログラム開始時からプログラム終了時までずっと寿命が持ちます。

これを利用して整数から特定の文字列定数を得るという関数を作ります。

const char *get_name_by_id(int id) {
    switch (id) {
    case 0: return "Taro"; break;
    case 1: return "Hanako"; break;
    default: return "Unknown"; break;
    }
}

この関数は↓のように使うことができます。

    printf("%s\n", get_name_by_id(0));  // Taro
    printf("%s\n", get_name_by_id(1));  // Hanako
    printf("%s\n", get_name_by_id(2));  // Unknown

便利な文字列定数ですがこのデータは変更できない点が注意が必要です。
変更を可能にしたい場合は文字配列を使う必要があります。

関連記事
C言語の文字列の使い方: 文字配列と文字列定数

列挙型と関数

では次に列挙定数と関数を見ていきます。
列挙定数はたとえば↓のように定義します。

enum Number {
    ONE = 1,
    TWO = 2,
};

この列挙定数を使って関数を定義すると例えば↓のようになります。

const char *number_to_string(enum Number n) {
    switch (n) {
    case ONE: return "ONE"; break;
    case TWO: return "TWO"; break;
    default: return "UNKNOWN"; break;
    }
}

この関数は列挙定数の値に応じて文字列定数に変換する関数です。
デバッグとかに使えそうですね。

この関数を使うと↓のようになります。

    printf("%s\n", number_to_string(ONE));  // ONE
    printf("%s\n", number_to_string(TWO));  // TWO
    printf("%s\n", number_to_string(3));  // UNKNOWN

列挙定数は型のようにも見えますが実際はただの整数です。
ですので↑の呼び出しもエラーにはなりません。
より厳密に型にしたい場合はtypedefキーワードを使いましょう。

関連記事
C言語の関数ポインタをtypedefする方法【型定義】
C言語の構造体をtypedefする方法

構造体と関数

最後に構造体と関数について見ていきましょう。
構造体変数は関数の返り値にも引数にも使うことができます。

↓のようなコードを見てください。

struct Size {
    int width;
    int height;
};

struct Size expand(struct Size size) {
    size.width += 2;
    size.height += 2;
    return size;
}

Size構造体はint型のwidthheightを持っている構造体です。
この値を拡張するのがexpand関数です。
この関数は引数にstruct Sizeを取り、返り値にstruct Sizeを返します。
ポインタは使ってないので構造体は引数も返り値もコピーされます。

この関数を使ってるところが↓です。

    struct Size s = {10, 20};
    s = expand(s);
    printf("%d %d\n", s.width, s.height);  // 12 22

関連記事
C言語で関数から複数の戻り値を返す【ポインタ、構造体】
【C言語】関数と構造体を組み合わせて使う
C言語で構造体を代入する方法

おわりに

今回はC言語の関数の定義について見てみました。
関数を定義してプログラミングを捗るようにしましょう。

(^ _ ^)

関数は

(・ v ・)

心の友



この記事のアンケートを送信する