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 函數(shù)
// 當然啦需要提前包含這些 extern 變量和 extern 函數(shù)的聲明
// 函數(shù)如果不顯示聲明成 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 函數(shù)
// 即使已經(jīng) include 的 module1.h 里的 static 函數(shù)的聲明
// 所以 static 變量和 static 函數(shù)是 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 函數(shù)的汤踏,即 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 函數(shù)的地址傳給 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 變量的地址往往是錯誤的媚狰,其內(nèi)存離開所在塊就被釋放了
// 但是可以返回局部 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(一)