首页 > 编程笔记 > C语言笔记

C语言static的用法(非常详细)

C语言中的 static 关键字可以用于变量和函数,改变它们的作用域和生命周期,它有下面几种用法。

1. 静态局部变量

当 static 用于局部变量时,它会改变变量的生命周期。普通的局部变量在函数调用结束后就会被销毁,而静态局部变量则在程序的整个运行期间都存在,但其作用域仍然限制在声明它的函数内。


来看一个例子:

#include <stdio.h>

void counter() {
    static int count = 0;  // 静态局部变量
    count++;
    printf("函数被调用 %d 次\n", count);
}

int main() {
    for (int i = 0; i < 5; i++) {
        counter();
    }
    return 0;
}

运行这段代码,输出结果为:

函数被调用 1 次
函数被调用 2 次
函数被调用 3 次
函数被调用 4 次
函数被调用 5 次

在这个例子中,static int count = 0 只在第一次调用 counter() 函数时初始化,之后每次调用都会保持并增加其值。如果没有 static 关键字,count 每次都会被重置为 0。

2. 静态全局变量

当 static 用于全局变量时,它会将变量的作用域限制在声明它的文件内。这意味着其他文件无法访问这个变量,即使使用 extern 关键字也不行。这种用法有助于实现信息隐藏,提高代码的模块化程度。


假设我们有两个源文件,file1.c 的源代码是:

#include <stdio.h>

static int secret_number = 42;  // 静态全局变量

void print_secret() {
    printf("秘密数字是:%d\n", secret_number);
}

file2.c 的源代码是:

#include <stdio.h>

extern int secret_number;  // 尝试访问 file1.c 中的 secret_number

int main() {
    printf("尝试访问秘密数字:%d\n", secret_number);  // 这将导致编译错误
    print_secret();  // 这是允许的,因为 print_secret 函数不是静态的
    return 0;
}

在这个例子中,file2.c 无法直接访问 file1.c 中的 secret_number,因为它被声明为静态的。这种方式可以防止全局变量被意外修改,增加了代码的安全性。

3. 静态函数

static 关键字也可以用于函数。静态函数的作用域被限制在声明它的文件内,这意味着其他文件无法调用这个函数。这对于创建只在特定文件中使用的辅助函数非常有用。


请看下面的例如:

// helper.c
#include <stdio.h>

static void internal_helper() {
    printf("这是一个内部辅助函数\n");
}

void public_function() {
    printf("这是一个公共函数\n");
    internal_helper();  // 可以调用静态函数
}

// main.c
int main() {
    public_function();  // 这是允许的
    internal_helper();  // 这将导致编译错误
    return 0;
}

在这个例子中,internal_helper() 函数只能在 helper.c 文件中使用,而 public_function() 可以在任何地方调用。这种方式可以有效地隐藏实现细节,只暴露必要的接口。

4. 类中的静态成员

虽然C语言本身不支持类,但在讨论 static 关键字时,值得一提的是它在 C++ 中的用法。在 C++ 类中,静态成员变量和静态成员函数属于类本身,而不是类的实例。


C++ 示例:

class MyClass {
public:
    static int count;
    static void printCount() {
        std::cout << "Count: " << count << std::endl;
    }
};

int MyClass::count = 0;  // 静态成员变量需要在类外初始化

int main() {
    MyClass::count = 5;
    MyClass::printCount();  // 输出 "Count: 5"
    return 0;
}

这个例子展示了如何在 C++ 中使用静态成员。静态成员可以不通过类的实例就能访问,它们在所有类的实例之间共享。

5. static 关键字的内存管理

使用 static 关键字声明的变量存储在程序的静态存储区,而不是栈上。这意味着它们在程序启动时就被分配内存,并在程序结束时才被释放。这与自动变量(如普通的局部变量)不同,后者在每次函数调用时在栈上分配内存,并在函数返回时释放。
 

静态存储的这种特性使得 static 变量特别适合于需要在多次函数调用之间保持状态的场景。然而,过度使用静态变量可能会增加程序的内存占用,因为这些变量在整个程序运行期间都占用内存。


声明:《C语言系列教程》为本站“54笨鸟”官方原创,由国家机构和地方版权局所签发的权威证书所保护。