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(一)
网友评论