‘全球’和’静态全球’之间的区别

全局变量的范围在所有文件中,而静态全局变量的范围只是声明它的文件。 为什么这样?

全局或静态全局变量存储在内存中的哪个位置?

存在一些混淆,因为C中的static可能意味着两种不同的东西。 一个是静态存储持续时间,另一个是内部链接。 在文件范围内用作关键字的static将给出与内部链接一起使用的函数或对象。

函数或对象的内部链接意味着如果在另一个“文件”中声明另一个函数(这实际上不是“文件”,而是翻译单元 – TU),那么该声明将引用另一个函数:声明的名称在该单元中将“链接”到与该另一个翻译单元中声明的名称不同的实体,该单元是该TU的“内部”。 这同样适用于对象。

无论文件范围变量是否使用static声明,它仍然具有静态存储持续时间:这意味着它贯穿整个程序,并在程序终止时死亡。 具有静态存储持续时间的对象的另一示例是字符串文字。 存储静态存储持续时间的对象未指定,但通常存储它们取决于它们是否已初始化:初始化文件范围变量通常存储在名为“.data”的部分中,而非初始化文件-scope变量通常存储在名为“.bss”的部分中。 请记住,如果变量未初始化,则在程序开始时将初始化为零:“。bss”部分通常由程序启动时的实现初始化为零。

我说“通常”到处都是,因为没有指定存储的东西。 例如,某些实现可以将字符串文字存储在只读部分中。 如果你有一个文件范围指针并且没有初始化它,那么实现会将它初始化为一个空指针,它不一定是所有空字节的对象:)

它们都存储在数据段中; 区别在于全局具有外部可见的链接器符号,而静态全局不具有。

全局变量的范围在所有文件中..而静态全局变量的范围只是声明它的文件..为什么会这样?

全局变量旨在可从任何模块访问 – 这种做法被认为是不良实践,并且只有在绝对必要时才应使用。

文件范围的静态变量(当你说“静态全局”时我假设你正在谈论的)可以由单个编译单元(通常是文件)中的例程访问 – 其原因是限制它的范围。 在修改使用该变量的代码时,您需要查看可能受影响的其他例程的位置有一个很好的限制。 它还减少了名称冲突的机会。

使用全局变量时,如果另一组模块碰巧也使用具有相同名称的全局变量用于不同目的,则必须将一个模块修改为使用其他名称。 静态变量不存在该问题。

无法从其他文件访问静态全局变量,而可以使用extern关键字访问全局变量。

C标准没有规定它们在存储器中的存储位置,并且它与C程序员无关。 访问变量的能力由编译器和链接器控制。

这是您在此主题领域提出的第二个问题。 使用像C这样的相对高级编程语言的主要原因之一是您不必担心这些问题。

我们使用静态属性隐藏模块内的变量和函数声明,就像我们在Java和C ++中使用公共声明和私有声明一样。 C源文件扮演模块的角色。 使用static属性声明的任何全局变量或函数对该模块都是私有的。 类似地,没有静态属性声明的任何全局变量或函数都是公共的,并且可以由任何其他模块访问。 虽然使用’global’关键字定义为变量或函数是一种很好的做法。

这两个变量都存储在可重定位文件的.data或.bss部分中。

关于静态和全局问题的重点问题

  1. 为静态变量分配的内存只有一次,即所有对象都由相同的内存共享,但是当涉及到全局变量时,内存将分配给每个对象。
  2. 静态和全局变量的寿命和范围不同。 首先,让我解释什么是生活和范围。 对象的生命周期确定对象是否仍在内存中,而对象的范围是它是否可以通过其名称访问变量.a)对象可能是活的,但不可见(不在范围内)b)如果一个对象不活动但在范围内(动态分配的对象除外,您通过指针引用对象)。
  3. 全局变量具有全局范围,我的意思是任何函数都可以从任何文件访问它,而静态变量具有文件范围,不可能从任何其他文件访问该变量。 当您想要使该变量可以访问该文件的所有函数,而不是另一个文件的函数时,此技术很有用。