c - 这个数组定义为静态而不是全局的是什么?

标签 c arrays

刚开始学C语言here .

在我上面链接的部分,作者想从函数返回一个数组,他写道:

C does not advocate to return the address of a local variable to outside of the function so you would have to define the local variable as static variable.

我理解阻止返回局部变量地址的原因。原因是局部变量在其范围之外不可用,因此将其地址置于函数之外可能会在运行时产生错误。

但我不明白的部分是为什么我们必须定义数组 Static 而不是 Global

将局部数组定义为静态只会改变它的生命周期,还是也会改变它的作用域?

这是我所说的程序:

#include <stdio.h>

/* function to generate and return random numbers */
int * getRandom( )
{
  static int  r[10];
  int i;

  /* set the seed */
  srand( (unsigned)time( NULL ) );
  for ( i = 0; i < 10; ++i)
  {
     r[i] = rand();
     printf( "r[%d] = %d\n", i, r[i]);

  }

  return r;
}

/* main function to call above defined function */
int main ()
{
   /* a pointer to an int */
   int *p;
   int i;

   p = getRandom();
   for ( i = 0; i < 10; i++ )
   {
       printf( "*(p + %d) : %d\n", i, *(p + i));
   }

   return 0;
}

更新:

这是上面程序的输出:

r[0] = 313959809
r[1] = 1759055877
r[2] = 1113101911
r[3] = 2133832223
r[4] = 2073354073
r[5] = 167288147
r[6] = 1827471542
r[7] = 834791014
r[8] = 1901409888
r[9] = 1990469526
*(p + 0) : 313959809
*(p + 1) : 1759055877
*(p + 2) : 1113101911
*(p + 3) : 2133832223
*(p + 4) : 2073354073
*(p + 5) : 167288147
*(p + 6) : 1827471542
*(p + 7) : 834791014
*(p + 8) : 1901409888
*(p + 9) : 1990469526

正如您在上面看到的,数组可以在 getRandom() 函数之外访问。这怎么可能?它是一个局部变量!

最佳答案

不同的技术概念和术语是

  1. “标识符的范围”(即声明的名称在哪里可见以便可以使用)与

  2. “对象的存储持续时间”,即我可以通过任何可用的方式、指针、索引、附加标识符或其他方式合法访问构成对象的内存多长时间.另一个词是“对象生命周期”。

所以说 int *p = getRandom();您正在引入一个具有 block 范围的标识符 p(因为它在 main 内部)标识一个具有自动存储持续时间的指针对象(因为它是在没有任何存储或链接限定的情况下声明的,例如“外部”或“静态”)。对于 p ,对象生命周期和标识符范围是相同的: block p在中声明和定义。

保存在这个本地指针对象中的是数组中元素的地址r具有静态存储期限rgetRandom() 中声明和定义. 标识符的范围 r getRandom() 的正文 block 在其中声明;你不能使用这个名字 r其他任何地方。但是由于“存储类说明符”static,数组对象 本身具有静态存储持续时间。这意味着数组对象的生命周期 就是程序的生命周期。 (是的,它甚至在 getRandom() 运行之前就存在了,但我认为没有办法合法访问它。)这就是为什么你可以在任何地方泄露它的地址并使用它,即使 getRandom() 也是如此。早就回来了。

编辑:为了完整起见:为什么有人会这样做而不只是为数组声明一个全局标识符?好吧,这是一种早期的封装形式(getRandom() 的后续实现可能会有所不同),并且它是实现单例的一种方式。

我怎么知道的?我读了 freely available C standard draft .与往常一样,要找到相关信息并不容易,但简单的关键字搜索会有所帮助。相关的是 6.2.1 标识符的范围和 6.2.4 对象的存储持续时间。当然,标准是枯燥和正式的,但它引入了适当的术语,并且经过一些调整后,非常容易理解。

关于c - 这个数组定义为静态而不是全局的是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31366158/

相关文章:

使用数组时 Javascript 向后循环变慢?

c - GCC 4.4.3 中的功能特定优化

c - 类似于 squeeze() 的用户定义函数

c - 为什么编译器不给我错误?

javascript - 对数组中对象的数据进行分组

arrays - 从三矩阵算法中找到给定的和 "total"

静态 c 函数可以返回本地 char 数组吗?

mysql - 从 C 语言将 16 位整数数组插入 MySQL

c - 有没有更好的方法来查找一个字符在 C 中的数组或字符串中出现的次数?

javascript - JSON - 如何在纯 JS 中获取值