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
函数中按名称可见。
我的问题是在 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 specifierstatic
, 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
函数中按名称可见。