静态和外部变量

时间:2010-07-01 19:31:02

标签: c

静态和外部变量之间有什么区别?制作静态变量有什么好处? 为什么我们更喜欢在多功能程序中创建外部变量?这本书说,其他它很晚才被初始化。我不明白。

2 个答案:

答案 0 :(得分:25)

问题是在C static中可以有不同的含义。我将尝试在以下段落中概述不同的情况。

如果在函数外定义变量,则文件中的所有函数都可以使用它。有时也称为“全局变量”。这意味着整个文件只有一个这个变量的实例。此外,变量的名称存储在生成的.OBJ文件中。后者很重要,因为如果另一个文件还定义了一个在函数外部具有相同名称的变量,则链接器假定它在两种情况下都是相同的变量,并将它们合并。 为了使此更清楚,最好将关键字“extern”添加到其中一个变量中。在这种情况下,我们说我们声明变量,而不是定义它。这是编译器/链接器的额外信号,表明我们实际上想要引用在其他地方定义的全局变量。

如果要定义全局变量,但又不想让其他文件可用,请先添加关键字static。关键字static告诉编译器变量名不能存储在.OBJ文件中。这意味着两个.C文件包含以下行:

static long MyGlobalVariable;

每个都有自己的变量。这两个变量都将被称为MyGlobalVariable。

如果在函数内定义变量,它将成为局部变量。它在调用函数时出现,并在函数完成后再次消失。 在某些情况下,您希望在函数调用之间保留变量的值。您可以通过使用全局变量(而不是局部变量)来执行此操作,但随后该变量可用于文件中的所有函数,您不一定需要这些函数。在这种情况下,您可以在变量之前放置关键字static,如下所示:

void MyFunction()
{
static long MyLocalVariable = 0;
++MyLocalVariable;
}

第一次调用函数时,MyLocalVariable将被“创建”并使用值0初始化。在函数结束时,变量不会被销毁,而是保留。因此,下次调用此函数时,变量的值将为1,而不是零。

在C中,将变量放在函数外部(作为全局变量)或在函数内部将其定义为静态并不重要。唯一的区别是可以访问变量的位置。

在C ++中,情况完全不同。如果你写这个(在函数之外):

MyClass MyGlobalVariable;

MyGlobalVariable将在应用程序启动时构建(这是:构造函数将被执行),甚至在调用main之前。但是,您无法真正控制构造所有全局变量的顺序。 所以如果另一个文件包含这个:

MyOtherClass MySecondGlobalVariable;

您无法确定是先构建MyGlobalVariable还是MySecondGlobalVariable。如果其中一个的构造函数依赖于另一个的存在(构造),这会产生问题。

另一方面,如果在函数中将变量定义为静态:

void MyFunction()
{
static MyClass MyStaticVariable;
}

然后在第一次调用函数时构造MyStaticVariable。有了这种结构,你可以这样写:

MyClass &getMyClass()
{
static MyClass MySelf;
return MySelf;
}

我们已经实现了一个单例,我们可以控制它何时构建。我们第一次需要它,它就构建了。

老实说,这种方法相当简单,因为它可能会导致多线程应用程序出现问题。在这种情况下,还有其他技巧。

答案 1 :(得分:-3)

“静态”或多或少意味着“这将永远存在”。根据具体情况,您会得到不同的结果:

 static int global_variable;
 void function()
 {
      static int global_function_variable;
 }

 class foo
 {
      static void function()
      {
           static int foo_function_variable;
           //...
      }
      static int foo_variable;
 }

global_variable - 只能在“翻译单元”中看到。 (由于标题或多或少被复制,这是否意味着标题中的静态全局存在作为包含在其中的所有cpp文件的单独变量?)

global_function_variable是在第一次调用function时创建的,并将在整个程序的生命周期中继续存在。值持续,因此如果在一个函数调用中更改它,则下一个函数调用将使用更改的变量。

foo::function()是一个可以像全局函数一样调用的函数;您不需要foo的实例来调用它。这意味着它没有有效的this指针。同样,即使没有foo_variable个对象,也存在foo。所有foo个对象都具有相同的foo_variable - 如果您在一个对象中更改它,则所有其他对象“看到”更改。

我认为

foo_function_variable就像global_function_variable一样。

extern背后的基本思想是控制变量的链接: 来自MSDN

// specifying_linkage1.cpp
int i = 1;
void other();

int main() {
   // Reference to i, defined above:
   extern int i;
}

void other() {
   // Address of global i assigned to pointer variable:
   static int *external_i = &i;

   // i will be redefined; global i no longer visible:
   // int i = 16;
}

extern int global_variable;

extern也可用于使用其他语言链接变量,最常见的是C.

global_variable是extern最常见的用法;它说在其他地方,有一个名为“global_variable”的变量,我们将使用该变量。某处,您需要声明变量而不使用 extern关键字,或者从未实际创建它。