ぷるぷるの雑記

低レイヤーがんばるぞいなブログ. 記事のご利用は自己責任で.

関数内のstatic変数を複数の関数で共有する

C言語で関数内のstatic変数を複数の関数で共有したいときは、関数ポインタを使おうという提案です.

以下のようにstatic変数を定義した関数func()に、実際にstatic変数を使いたい関数ポインタを渡し、func()にstatic変数を引数にセットしてもらおうという算段です.

static変数を実際に使用する関数のインターフェースが一致するとは限らないので、引数の型をvoid * 型にしてお茶を濁しましょう.

#include<stdio.h>

void func(void (*callee)(void *, void *));
void func1(void *para1, void *para2);
void func2(void *para1, void *para2);


int main()
{
    func(func1);
    func(func2);
    func(func1);

    return 0;
}

void func(void (*callee)(void *para1, void *para2)) {
    static int val;
    callee((void*)val++, (void*)3);
}

/* static変数をfuncに注入してもらう */
void func1(void *para1, void *para2) {
    
    int shareVal = (int)para1;
    int cnt = (int)para2;

    for (int i = 0; i < cnt; i++) {
        printf("func1 shareVal=%d\n", shareVal);
    }
}

/* static変数をfuncに注入してもらう */
/* func1とインターフェースを合わせるために引数を2つ受け取るが、実際に使用するのは1つ目だけ */
void func2(void *para1, void *para2) {
    int shareVal = (int)para1;
    printf("func2 shareVal=%d\n", shareVal);
}

/* 実行結果 */
func1 shareVal=0
func1 shareVal=0
func1 shareVal=0
func2 shareVal=1
func1 shareVal=2
func1 shareVal=2
func1 shareVal=2


static変数のアドレスを渡すようにすれば値の参照だけではなく更新もすることが出来ます.

#include<stdio.h>

void func(void (*callee)(void *, void *));
void func1(void *para1, void *para2);
void func2(void *para1, void *para2);


int main()
{
    func(func1);
    func(func2);
    func(func1);

    return 0;
}

void func(void (*callee)(void *para1, void *para2)) {
    static int val;
    callee((void*)(&val), (void*)3);
}

/* static変数の参照だけ */
void func1(void *para1, void *para2) {
    
    const int *pShareVal = (int*)para1;
    int cnt = (int)para2;

    for (int i = 0; i < cnt; i++) {
        printf("func1 shareVal=%d\n", *pShareVal);
    }
}

/* static変数を変更する */
void func2(void *para1, void *para2) {
    int *pShareVal = (int*)para1;
    printf("func2 shareVal=%d\n", *pShareVal);
    *pShareVal = 10;
}

/* 実行結果 */
func1 shareVal=0
func1 shareVal=0
func1 shareVal=0
func2 shareVal=0
func1 shareVal=10
func1 shareVal=10
func1 shareVal=10