static 是 C 语言的关键字,能用在变量和函数上,作用都是收窄活动范围。最常见的两种:static 局部变量和 static 函数。

static 局部变量:出了作用域还剩着

普通局部变量一离开自己的函数就消失,下次进来重新初始化。static 局部变量反着来:值在作用域之外依然保留,下次进入函数不会重新初始化,而是接着上次的值走。

先看一段失败的计数器:

#include <stdio.h>

int runner() {
    int count = 0;
    count++;
    return count;
}

int main() {
    printf("%d ", runner());   // 每次进来都是 1
    printf("%d ", runner());   // count 用完就没了,又是 1
    printf("%d\n", runner());
    return 0;
}

输出 1 1 1,因为 count 在函数返回时就被清掉了,三回全是从 0 加一。

加上 static 就能记数了:

#include <stdio.h>

int runner() {
    static int count = 0;   /* 只初始化一次 */
    count++;
    return count;
}

int main() {
    printf("%d ", runner());   // 1
    printf("%d ", runner());   // 2
    printf("%d\n", runner());  // 3
    return 0;
}

输出 1 2 3。static 变量的初始化语句只在程序启动时执行一次,之后它一直在后台记着上次的值。经典场景就是统计函数被调用了多少次。

static 全局变量:只在本文本文件可见

C 语言的全局变量默认是全局可见的,别的文件用 extern 也能访问。加 static 就把它的作用域收到定义它的那个文件里,别的文件碰不到。作用对照:

类别默认作用域static 后
局部变量所在函数内函数内,但值跨调用保留
全局变量整个程序(跨文件)只限本文件
函数整个程序(跨文件)只限本文件

static 函数:装进文件这个房间

函数默认是全局的,别的文件也能调用。用 static 修饰后,该函数只在本文件内可见:

static void fun(void) {
    printf("我是我这个文件里的私有函数。\n");
}

大型项目里,一个 .c 文件自带的辅助函数大多用 static 声明,防止和别的文件撞名,也明确告诉别人这是我的内部工具。

static vs 全局

一句话区别:static 变量只在包含它的那个文件里可见,全局变量别的文件也能用。想藏着掖着就用 static。

练手题:不传任何累计值参数给函数,用 static 变量实现一个累加器 sum(n),连续调用 sum(55)、sum(45)、sum(50),每次都返回到当前为止的总和。