静态是什么意思?

时间:2019-01-29 13:59:20

标签: c static

考虑以下代码:

static uint8_t tab[] = {1, 2};

void foo() {
    uint8_t tab2[] = {1, 2};
}

我在这里有两个数组,一个数组用static关键字,第二个数组在函数内。我应该如何正确命名每个人?因为那两个是静态的。我知道tab数组将永远存在的区别与tab2不存在,foo()数组仅在执行函数tab2时存在。如果void bar() { static uint8_t tab[] = { 1, 2 }; } 是在函数退出后死亡的静态数组,是否不应该将其称为另一个?那些有助于编程理论的数组的专有名称是什么?

另一个例子:

NewTest() {
    PageFactory.initElements(driver, this);
}

根据此类变量的编程理论,专有名称是什么? “静态为静态”数组?

6 个答案:

答案 0 :(得分:6)

static关键字的意思是static storage duration and internal linkage(除非在块范围内,它表示静态存储持续时间和 no 链接,因为从不链接块范围的事物。)

您的tab2 不是静态的,它具有自动的存储期限,并且没有链接。 (甚至还有一个关键字auto,它是隐含的,但是通常不使用。不要将其与C ++混淆,C ++已经“回收”了该关键字以具有完全不同的含义。)

您赋予变量的标识符-例如tabtab2 –由您决定。但是,它们 的含义由以下语言很好地定义:

  • 您的第一个tab是两个uint8_t静态全局数组。它具有静态存储持续时间和内部链接。
  • 您的tab2是由两个uint8_t组成的 block范围数组。它具有自动存储时间和 no 链接。
  • 您的第二个tab是由两个uint8_t组成的静态块范围数组。它具有静态存储期限和 no 链接。

答案 1 :(得分:2)

这里似乎存在误解。这不完全是您的错,在C语言中看到“静态”意味着至少有两种不同的情况。

您的tab2不是静态的。它没有静态存储持续时间,也没有与静态存储相关的任何方式。它只是一个数组。这是一个局部变量,它是一个数组。

您的tab是一个全局数组,可为其提供静态存储持续时间,并且由于关键字static而具有内部链接。如果在函数中,则为“函数静态”。

如果我是你,我不会为术语担心太多。相反,请担心使程序执行您想要的操作!

答案 2 :(得分:2)

清除条款:

1) static uint8_t tab[] = {1, 2};

2) void foo() { uint8_t tab2[] = {1, 2}; ...

范围:
1)是在文件作用域中声明的变量。 2)是在本地范围中声明的变量。范围确定在何处可访问变量。

  • 显然,局部变量只能在声明它们的范围内访问。
  • 在声明了变量的整个翻译单元中,都可以访问文件范围变量。转换单元是.c文件及其包括的所有.h文件。

存储期限:

  • 静态存储持续时间表示变量将在程序执行期间持续存在。总是在调用main()之前将此类变量初始化为零或特定值。
  • 自动存储期限表示当程序计数器离开声明该变量的范围时,该变量将不再有效。除非由程序员明确初始化,否则它们具有不确定的值。

在文件作用域声明的所有变量都具有静态存储持续时间。
所有声明为static的变量都具有静态存储持续时间。
在本地范围内声明的所有变量(不带static)都具有自动存储期限。

extern等还有其他一些情况,但这在这里不相关。这里有链接一词,在这里我不会解决。)

知道这一点,然后“因为这两个是静态的”是没有道理的。它们具有静态设置的固定大小,但这就是它们的共同点。


关于命名,这是主观的,并且取决于您自己的编码标准。给他们直观的名称来说明它们包含的内容,而不是它们的类型。

一些较旧的编码标准喜欢将声明为static的文件范围变量视为私有变量,因此使用了_前缀来表明这一点。但这是一种不好的做法,因为它违反了C标准(和POSIX标准)的命名规则。

答案 3 :(得分:1)

  

归因于编程理论的那些数组的专有名称是什么?

命名标识符不是编程理论的一部分。如何命名它们取决于最佳实践,惯例,公司标准等。而如何做到这一点是基于意见的。

答案 4 :(得分:1)

C有很多 classes (名称是我的)变量,并且范围(变量可以访问代码的哪一部分)和持续时间各不相同。

在文件级别(任何功能之外):

  • 没有限定符:持续时间:程序的完整长度,范围:文件,可以作为外部访问:从程序的任何编译单元(据说具有外部链接)
  • 静态:持续时间:程序的完整长度,范围:文件,可以作为外部访问:否(表示具有内部链接)

在函数或集团内部:

  • 没有限定词:持续时间:团体(变量在声明该团体的末尾消失),作用域:团体,可通过外部访问:否(表示为自动,并且没有链接)
  • 静态:持续时间:程序的完整长度,范围:块,可以通过外部访问:否(表示块是静态的,没有链接)

此外,可以将变量声明为extern。在这种情况下,仅声明变量,并且必须在同一编译单元或另一编译单元中的具有相同声明的其他位置进行定义。

为详尽起见,C在持续时间上还有另一类:已分配。它用于通过malloc创建的对象,这些对象将持续存在,直到显式释放它们为止。但要注意:程序员有责任使用正常范围规则保留指向该对象的指针,以便能够释放它。

答案 5 :(得分:1)

在文件范围声明中,

static表示“在此翻译单元本地”。

示例:

static int variable=42; 
static int function(){return 0;}
//won't be visible in other translation units

static在块范围的声明中表示“具有静态存储持续时间”:

示例:

uint8_t *bar() {
  static uint8_t tab[] = { 1, 2 };
  return  &tab[0]; 
  //ok with static but pretty much always an error otherwise
}
int how_many_times_i_ran(){ static unsigned x; return x++; }

static位于“数组类型”函数参数的括号内,表示后面的整数表达式表示指针必须指向的最小元素数。

void take3(int Three[static 2+1]); 

void call()
{
    take3((int[3]){0}); //OK
    take3(0); //undefined
    take3((int[2]){0}); //undefined
}