C中不同类型的静态

时间:2013-04-29 17:17:04

标签: c variables

我知道C中有三种类型的静态去除:

1:常量 - 常量静态变量,例如:static const int i = 5;

2:Changable - 只是一个普通的静态变量,例如:static int hi = 10;

这是我的问题

还有另一种形式的静态,它采用“代码”的形式。这是什么意思,你能举个例子吗?

谢谢!

修改: 静态/常量变量是否存储在堆栈/堆上?

5 个答案:

答案 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)

  

静态/常量变量是否存储在堆栈/堆上?

嗯,不,他们是“全球”空间的一部分。 堆栈和堆用于“动态”内存分配,而不是静态!