how/when是C语言中声明的函数中的静态变量吗?

how/when is a static variable in a function declared within C language?

我的问题是在 foo() 函数中,sa 变量似乎是在那里声明和初始化的,但是因为它是静态的,所以编译器会在第一次后忽略它吗?为什么它没有初始化回值 10 即使它是静态的?

#include <stdio.h>

void foo()
{
int a = 10;
static int sa = 10;

a += 5;
sa += 5;

printf("a = %d, sa = %d\n", a, sa);
}


int main()
{
int i;

for (i = 0; i < 10; ++i)
    foo();
}

这会打印:

a = 15, sa = 15
a = 15, sa = 20
a = 15, sa = 25
a = 15, sa = 30
a = 15, sa = 35
a = 15, sa = 40
a = 15, sa = 45
a = 15, sa = 50
a = 15, sa = 55
a = 15, sa = 60

在 C 中,static 表示它在调用之间持续存在,因此它与您的建议相反:初始化 发生在第一次调用时。

引用 C11 标准,章节 §6.2.4,对象的存储持续时间

An object whose identifier is declared without the storage-class specifier _Thread_local, and either with external or internal linkage or with the storage-class specifier static, has static storage duration. Its lifetime is the entire execution of the program and its stored value is initialized only once, prior to program startup.

因此,sa 并非在每次调用时都被初始化。它只初始化一次并保存最后存储的值。

也就是说,关于价值的保留,引用相同的规范,

[..] An object exists, has a constant address, and retains its last-stored value throughout its lifetime. [...]

将它放在函数中的原因是将变量的范围限制在函数范围本身。

如果您在全局范围内声明 sa,您的程序将以相同的方式运行,尽管其范围会有所不同:

int sa = 10;

void foo()
{
    int a = 10;

    a += 5;
    sa += 5;

    printf("a = %d, sa = %d\n", a, sa);
}

您可能想要在 foo 中声明 sa 的原因是限制其访问。

static 可以声明一个只在编译单元内可见的函数。

在函数中使用 static 变量, a) 保留一块内存来保存单个值(与线程无关),以及 b) 只初始化一次。在 C++11 中,这保证是线程安全的,尽管我认为在 C 中没有这样的保证。

所以预留了一块内存。在函数被调用之前,它不会被设置

具有 static 存储持续时间的对象在程序启动时分配和初始化 一次 ,并且该存储一直保留到程序终止。

因此,sa 变量是在程序启动时分配和初始化的,而不是在 foo 首次执行时分配和初始化的,并且它在对 foo 的调用之间持续存在。

但是,sa 变量仅在 foo 函数中按名称可见。