2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

(C言語)『関数へのポインタ』と『typedefを使った,関数へのポインタ定義』を解説!

Last updated at Posted at 2022-09-13

(修正) 関数の引数を空白からvoidにしました!
ご指摘していただきありがとうございます.

前書き

12 ステップで作る組込みOS自作入門 (著者:坂井 弘亮, 発行年:2010年, 出版社:カットシステム)を読ませていただいてます.
この本の7章で,関数へのポインタという技術が使用されました.
私は,ここで初めて関数へのポインタというものを知り,調べることになりました.
調べてみて,得た知識を共有したいと思い,この記事を投稿させていただきます.

概要

この記事では,C言語における,
関数へのポインタ
typedefを使った,関数へのポインタ定義

の2つを解説,使い方を紹介しています.

サンプルコードがございますので,
実際に動かしてみて理解を深めていただけると幸いです.

また,この記事に誤植がある場合,
お手数ですがコメントで指摘していただけると幸いです.

対象読者

・ 関数へのポインタ
・ typedefを使った,関数へのポインタ定義

について学びたい人.

・C言語の変数のポインタについてある程度理解している人
(変数のポインタがわからないとかなり難しいかも...)

関数へのポインタ

関数へのポインタは,変数へのポインタと同じようなものです.


関数へのポインタfを定義したいなら,

void (*f)(void); //返り値なし,引数なし

となります.1

関数へのポインタfは,返り値なし,引数なしなので,
返り値なし,引数なしの関数を受け取ることができます.
返り値と引数は一致していないといけません. 2

わかりにくいので,実際にプログラムを見てみましょう.
使い方は以下のようになります.

main.c
#include "stdio.h"

// 関数ポインタfに渡す関数
void show(void) // 返り値なし,引数なし
{
    printf("Hello, World\n");
}

// 関数ポインタfを定義
void (*f)(void); //返り値なし,引数なし

int main(void)
{
    //関数ポインタfに,show関数のポインタを渡す
    //返り値なし,引数なしが一致している.
    f = show;
    f(); //関数ポインタfを使うとshow関数と同じ動作をする

    return 0;
}

実行すると,このような結果になります.

Hello, World

typedefを使った,関数へのポインタ定義

typedef void (*func)(void);
func f;

このような書き方をした場合,
1行目で,func型は返り値なし,引数なしの関数型と定義されます.
2行目で,func型関数へのポインタfが宣言されます.

わかりにくいので,実際にプログラムを見てみましょう.
以下のプログラムを見てください.

main.c
#include "stdio.h"

// 関数ポインタfに渡す関数
void show(void) // 返り値なし,引数なし
{
    printf("Hello, World\n");
}

// 関数ポインタ型funcをtypedef定義
typedef void (*func)(void); //返り値なし,引数なし

int main(void)
{
    //関数ポインタ型funcから関数ポインタfを定義する.
    func f;
    //関数ポインタfにshow関数のポインタを渡す.
    //返り値なし,引数なしが一致している.
    f = show;
    f(); //関数ポインタfを使うとshow関数の動作をする

    return 0;
}

応用例

せっかくなので,
返り値がint型,引数が2個で両方ともint型の
サンプルプログラムを載せます.

このときもやはり,引数と返り値を一致させなくてはいけません.2

main.c
#include "stdio.h"

// 関数ポインタfに渡す関数
int add(int a, int b) // 返り値int,引数int, int
{
    return a+b;
}

// 関数ポインタ型funcをtypedef定義
typedef int (*func)(int, int); // 返り値int,引数int, int

int main(void)
{    
    int a = 3, b = 5;

    //関数ポインタ型funcから関数ポインタfを定義する.
    func f;
    //関数ポインタfにadd関数のポインタを渡す.
    f = add;

    // 関数ポインタfをadd関数のように使う.
    printf("%d+%d=%d\n", a, b, f(a, b));

    return 0;
}

最後に

ここまで見てくださりありがとうございました!

  1. コメントのご指摘の通り,
    引数をvoidにすることで,コンパイラに引数はないことを教えてあげないといけません.
    引数が空白の場合,関数呼び出し時に値を渡しても,コンパイルはエラーを出してはくれません!
    引数がvoidなら,コンパイルはちゃんとエラーを出してくれます!

  2. 試してみたところ,
    引数は一致してないとコンパイルエラーになりましたが,
    返り値は一致してなくてもコンパイルエラーになりませんでした.
    しかし警告は出たので,やはり一致させなくてはいけないと思います. 2

2
1
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?