这里的static有什么作用?

3
GNU的getopt_long示例中,一个在文件作用域中定义的标志使用了static
/* Flag set by ‘--verbose’. */
static int verbose_flag;

在一个while循环块作用域中定义的long_options结构体中:

static struct option long_options[]

这里使用static是为了防止其他文件访问变量。在这两种情况下,static的使用方式相同,在结构体中更有效率,因为它保存在内存的同一位置并且不会重新初始化。

3个回答

2
如果在文件作用域中使用static关键字定义变量,那么它就只能在该文件中使用,没有这个关键字的话,你可以使用extern关键字在另一个文件中使用它。
对于函数也是一样。如果C语言中的函数在文件中被声明为静态的,那么它只能在该文件中使用,而不能在其他文件中使用。
所以,是的,我想这是为了防止在其他文件中使用它。

0
我会按相反的顺序做:
static struct option long_options[]

static用于变量选项,使其在while循环执行多少次都可以被声明一次。

但你应该将其视为一个整体(从你的链接中提取):

...
while (1)
{
...
 static struct option long_options[] =
    {
      /* These options set a flag. */
      {"verbose", no_argument,       &verbose_flag, 1},  // <-- IMPORTANT HERE !
      {"brief",   no_argument,       &verbose_flag, 0},  // <-- IMPORTANT HERE !
      /* These options don’t set a flag.
         We distinguish them by their indices. */
      {"add",     no_argument,       0, 'a'},
      {"append",  no_argument,       0, 'b'},
      {"delete",  required_argument, 0, 'd'},
      {"create",  required_argument, 0, 'c'},
      {"file",    required_argument, 0, 'f'},
      {0, 0, 0, 0}
    };
...
}
...

而且,由于您的声明引用了一个变量,在这种情况下是verbose_flag,它应该在迭代中可用,否则您将在下一次迭代中失去该变量,然后引用不再存在的东西,这将是未定义的行为。这就是为什么verbose_flag是文件全局的原因。它被设置为静态以确保该变量仅可从此文件使用,而不可从其他文件使用。


1
verbose_flag 在文件作用域中,即使没有 static 也不会在迭代之间失去其值。它被设置为 static 是出于不同的原因... - hyde
@hyde 我正想评论同样的事情。 - qwr
@hyde 是的,你说得对。那么这意味着变量完全局限于本文件中,确保其他文件不会使用它。 - dkg

0

当静态变量出现在C/C++文件的任何代码块中时,它是一个声明修饰符,表示该变量不能被其他文件访问;当静态变量出现在代码块中时,它表示该变量是"静态"的。verbose_flag适用于前者,而long_options适用于后者。


1
最好讨论翻译单元而不是文件。翻译单元基本上是预处理器剩下的内容,因此它还包含所有.h文件中的代码。在.h文件中进行static声明会在每个包含该.h文件的翻译单元中创建一个独立的副本。因此,说“其他文件无法访问”是不准确/误导的。 - hyde
1
@hyde 为什么不写下你自己的答案呢?当然,提出改进意见是可以的,但评论并不能真正帮助讨论本身。 - edmz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接