我知道C中有三种类型的静态去除:
1:常量 - 常量静态变量,例如:static const int i = 5;
2:Changable - 只是一个普通的静态变量,例如:static int hi = 10;
这是我的问题
还有另一种形式的静态,它采用“代码”的形式。这是什么意思,你能举个例子吗?
谢谢!
修改: 静态/常量变量是否存储在堆栈/堆上?
答案 0 :(得分:8)
也许你在谈论static function?
这是“静态”一词的特定用法,它与静态变量完全不同。
当您声明一个函数“static”时,这意味着它无法从另一个源文件链接。它通常用于将某些功能保持为“私有”。
[编辑]请注意,理论上,功能代码仍然可以使用指针从另一个源文件访问,但这并不是访问函数的常规方式(当然也不是最简单的方法)。感谢Eric Postpischil指出这一点。
令人遗憾的是,C标准中使用的同一个词“static”表示两种不同的东西,具体取决于用于函数或变量。
[edit] :这是一个不同的问题,但无论如何:在静态变量的情况下,它们既不在堆中也不在堆栈中分配。它们是静态的,这意味着它们被分配在静态空间中,在启动时由编译器直接分配。 Stack用于内部函数变量,heap用于malloc()/ free()。
答案 1 :(得分:4)
This link应该回答你的问题。
值得注意的是,除非您对C编译过程有足够的了解,否则这将是值得怀疑的。
可以找到GCC的一个很好的参考资料here。
我相信你在询问静态功能 ..所以......
静态功能
默认情况下,C中的函数是 extern ,这意味着该函数可以在同一项目的任何其他文件中使用(和相同的代码)当然)。
如果你不喜欢这种情况,并且想要将函数限制在定义它的文件中,你可以将它设为 static 。
答案 2 :(得分:1)
关键字static
在C中以多种不同的方式使用。(有一个笑话,需要任何新版本的ISO C标准来为static
创造新的含义。)
快速摘要:块范围定义上的static
关键字为实体提供静态存储持续时间;在文件范围内,定义已经有静态存储持续时间,而是给它们内部链接。
对象可能具有多个存储持续时间中的任何一个。仅在执行封闭块期间,在运行时存在具有“自动”存储持续时间的对象。在整个程序执行期间存在具有“静态”存储持续时间的对象。 (还有“已分配”和C11中的新内容,“临时”存储持续时间,我不会进入。)
标识符的任何定义也都有“链接”,可以是外部,内部或无。链接控制标识符是否可用于翻译单元(基本上是源文件,但#include
d文件不是单独的翻译单元)。顾名思义,链接与链接器有关。您可以在两个不同的源文件中使用具有内部链接的相同标识符,它将引用两个不同的实体。但是,如果标识符具有外部链接,则它应该只定义一次,并且可以在多个源文件中声明(通常使用extern
);所有这些声明都将引用同一个实体。
如果在块范围内定义对象(变量)(即在函数体内),则默认情况下它具有自动存储持续时间(并且没有链接)。添加关键字static
会为其提供静态存储持续时间,因此它存在并保留其对函数调用的值。 (它不会影响标识符的可见性)。
如果在文件范围(即任何函数体外)定义对象,则默认情况下它具有静态存储持续时间和外部链接。将关键字static
添加到定义不会影响其存储持续时间,但会更改其从外部到内部的链接,将名称隐藏在其他转换单元中。函数没有存储持续时间(只要程序正在运行,它们的代码就存在),但static
以相同的方式影响它们的链接,将它从外部更改为内部。
(对于数组类型的函数参数,C99为static
添加了另一个含义,与其他用途无关。)
答案 3 :(得分:1)
我认为有必要澄清我们正在谈论的内容,并尝试使用正确的措辞。
const
限定符与static
关键字无关。
从技术上讲,static
关键字出现在声明中,它通常是存储类说明符,但是从C99它也可以在数组声明符中,尽管这很不寻常。
当它是存储类说明符时,就像您发布的声明一样,它会影响标识符的链接(文件之间的可见性)和存储持续时间(生命周期)标识的对象,但不是标识符的范围。
6.2.2标识符的链接
[...]在一个翻译单元中,具有内部链接的标识符的每个声明表示相同的对象或功能。 [...]
如果对象或函数的文件范围标识符的声明包含存储类说明符
static
,则标识符具有内部链接。 30)
30)函数声明只有在文件范围内时才能包含存储类说明符
static
;见6.7.1。
因此,标识符只能在翻译单元(即预处理后的源文件)中被声明,是对象还是函数 (也许这就是你要找的东西)。因此,您可以使用声明“私有”函数只在一个文件中使用。
static void foo(void)
{
// ...
}
static
关键字也与inline
函数说明符一起使用,它具有特定的链接语义:https://stackoverflow.com/a/216546/1202636
当我们不在文件范围但是在一个更受限制的(函数内部static
声明)中时,链接问题变得无关紧要,因为这样的标识符根本没有链接。
6.2.4对象的存储持续时间
使用外部或内部链接或使用存储类说明符
static
声明其标识符的对象具有静态存储持续时间。它的生命周期是程序的整个执行,它的存储值只在程序启动之前初始化一次。
这个仅适用于对象标识符,它会影响对象的生命周期,例如让变量在调用之间保留其值以及初始化。
(只是说,这样的对象也用默认值初始化)
正如我所说,static
关键字的使用较少:它可以在函数原型中的数组声明符中使用,告诉编译器作为参数给出的数组至少包含 n < / em>元素。这是标准中的(修改)示例:
void f(double a[static 3][5]);
声明指定在对
a
的任何调用中对应于f
的参数必须是指向至少三个5个双精度数组中的第一个的非空指针,而其他数组则不是。
静态/常量变量是否存储在堆栈/堆上?
同样,const
ness与存储对象的地方无关。该标准没有说明该地方的任何内容,通常有专门的区域,但这是一个不同的已经回答的问题:where are static buffers allocated?
答案 4 :(得分:1)
静态/常量变量是否存储在堆栈/堆上?
嗯,不,他们是“全球”空间的一部分。 堆栈和堆用于“动态”内存分配,而不是静态!