static(二)

module1.h

#include <stdio.h>

typedef int (*myfunc1)();

typedef void (*myfunc2)(int);

int get_extern_data();

void set_extern_data(int data);

static int get_static_data();

static void set_static_data(int data);

int get_static_data2();

void set_static_data2(int data);

myfunc1 get_static_func1();

myfunc2 get_static_func2();

int* get_local_static_data();

module1.c

#include "module1.h"

static int static_data = 1;

int extern_data = 100;

int get_extern_data()
{
    return extern_data;
}

void set_extern_data(int data)
{
    extern_data = data;
}

static int get_static_data()
{
    return static_data;
}

static void set_static_data(int data)
{
    static_data = data;
}

int get_static_data2()
{
    return static_data;
}

void set_static_data2(int data)
{
    static_data = data;
}

myfunc1 get_static_func1()
{
    return &get_static_data;
}

myfunc2 get_static_func2()
{
    return &set_static_data;
}

int* get_local_static_data()
{
    static int local_static_data = 10;
    return &local_static_data;
}

module2.c

#include <stdio.h>
#include "module1.h"

int main(int argc, char const* argv[])
{
    // comment 0 ====================================================
    // module2.c 里可以直接访问 module1.c 的 extern 变量和 extern 函数
    // 当然啦需要提前包含这些 extern 变量和 extern 函数的声明
    // 函数如果不显示声明成 static 的话,默认就是 extern 的
    printf("%d\n", get_extern_data());  // 100
    set_extern_data(101);
    printf("%d\n", get_extern_data());  // 101
    // ==============================================================


    // comment 1 ====================================================
    // module2.c 里不能直接访问 module1.c 里的 static 变量和 static 函数
    // 即使已经 include 的 module1.h 里的 static 函数的声明
    // 所以 static 变量和 static 函数是 file private 的
    // printf("%d\n", get_static_data());      // link error
    // set_static_data(2);                     // link error
    // printf("%d\n", get_static_data());      // link error
    // ==============================================================


    // comment 2 ====================================================
    // 但是 module2.c 可以间接地访问 module1.c 里的 static 变量
    // 比如 module1.c 里定义一个 extern 的接口,该接口是有权限访问所在文件
    // 的 static 变量和 static 函数的,即 module2.c 对 module1.c 里的
    // static 变量的访问由 module1.c 的 extern 接口代理
    printf("%d\n", get_static_data2());  // 1
    set_static_data2(3);
    printf("%d\n", get_static_data2());  // 3
    // ==============================================================


    // comment 3 ====================================================
    // 除了上述提到的代理模式,还能让 module1.c 的 extern 接口将 module1.c
    // 的 static 变量的地址和 static 函数的地址传给 module2.c
    // 于是 module2.c 可以通过指针进行间址访问另一文件的 static member 了
    myfunc1 getStaticFunc1 = get_static_func1();
    myfunc2 getStaticFunc2 = get_static_func2();
    printf("%d\n", (*getStaticFunc1)());  // 3
    (*getStaticFunc2)(4);
    printf("%d\n", (*getStaticFunc1)());  // 4
    // ==============================================================


    // comment 4 ====================================================
    // 返回局部 auto 变量的地址往往是错误的,其内存离开所在块就被释放了
    // 但是可以返回局部 static 变量的地址,其生命周期与程序运行周期一样长
    // module2.c 可以通过 module1.c 的 extern 接口得到 module1.c 的
    // local static 变量的指针,进而间址访问
    int* local_static_data = get_local_static_data();
    printf("%d\n", *local_static_data);  // 10
    *local_static_data = 11;
    local_static_data = get_local_static_data();
    printf("%d\n", *local_static_data);  // 11
    // ==============================================================


    return 0;
}

传送门:static(一)

推荐阅读更多精彩内容