C 静态变量和全局变量都位于数据段中。不过,静态变量的作用域是有限的。为什么?

C 静态变量和全局变量都位于数据段中。不过,静态变量的作用域是有限的。为什么?,c,C,在典型的C程序中,静态变量和全局变量都位于数据段上。静态变量的作用域仍然限于文件。相反,全局变量可以从任何地方访问。为什么会发生这种情况,尽管它们都驻留在同一内存中?静态变量的概念是它们不是全局变量,并且不会“污染”全局名称空间。这意味着我可以在5个不同的函数中使用变量“count”,它们不会冲突。作用域将变量限制在其上下文中。从技术上讲,您可以访问任何内容。编译器只是不会给你一个内存地址——你必须自己得到它。不知何故。出于设计 staticat global scope是您用来表示“我希望这些

在典型的C程序中,静态变量和全局变量都位于数据段上。静态变量的作用域仍然限于文件。相反,全局变量可以从任何地方访问。为什么会发生这种情况,尽管它们都驻留在同一内存中?

静态变量的概念是它们不是全局变量,并且不会“污染”全局名称空间。这意味着我可以在5个不同的函数中使用变量“count”,它们不会冲突。作用域将变量限制在其上下文中。

从技术上讲,您可以访问任何内容。编译器只是不会给你一个内存地址——你必须自己得到它。不知何故。

出于设计

static
at global scope是您用来表示“我希望这些变量在范围内受到限制;我不想关心其他模块是否声明了相同名称的变量”的关键字。使用此关键字的原因与不使用它的原因不同,事实上正是它存在的原因

注意,关键字在不同的上下文中表示不同的事物;在函数范围内,static表示“此变量的内容应在函数调用之间保持不变”

内存中数据的实际排列结果是一个实现细节,编译器和平台之间会有所不同

Why does it happen, although both resides in the same memory?
简短回答:-

根据C11标准(6.2.2标识符链接)第4段:

如果对象或对象的文件作用域标识符的声明 函数包含storageclass说明符静态标识符 具有内部链接

内部链接意味着其仅在其内部可见

详细答案:

全局变量(无静态)具有外部链接,这意味着它对其他平移单元可见

当您使用文件范围声明静态变量时,它具有内部链接,但当您使用块范围声明静态变量时,它没有链接

让我们具体了解几个术语。(灵感来源)

C变量具有以下链接之一:

  • 无链接:-具有块范围的变量没有链接。这意味着它们是定义它们的块的私有变量。所有具有自动、线程和动态存储持续时间的变量都具有此链接,以及在块范围内声明为静态的变量。 具有文件作用域的变量可以具有内部链接或外部链接
  • 内部链接:-可以从当前转换单元的所有范围引用变量。在文件范围内声明的所有变量都具有此链接,包括在文件范围内声明为静态的变量
  • 外部链接:-可以从整个程序中的任何其他翻译单元引用变量。所有声明为extern或const且没有显式存储类说明符(但不是静态)的变量都具有此链接
e、 g-

通过在文件级别声明变量static(
static
在函数中具有不同的含义),您禁止其他单元访问它,例如,如果您尝试在另一个单元内使用该变量(使用
extern
声明),链接器将找不到此符号


Emphasis mine:)

从技术上讲,是否可以访问“所有内容”取决于实现。并非所有的C实现都使用简单、平坦的内存模型。而且,即使在简单的内存模型中,C计算模型中的所有对象也不是都存在于优化后的最终实现中。这就是它的定义方式,早在时间的迷雾中。C的开发人员不想在“local”或“nonglobal”之类的词上浪费一个新的关键字,所以他们回收了“static”。术语“variable”在C中没有很好的定义。事实上,“Language”一节的规范性文本中根本没有使用它。有对象(存储区域)和标识符(名称)。这里的问题是:标识符具有作用域和链接,对象具有存储持续时间
static
不会更改对象的存储持续时间(对于“全局变量”),它只是更改标识符的链接。
int i = 5; // file scope, external linkage
static int j = 3; // file scope, internal linkage
...
...
int main()
{
...
...
}
int func ()
{
static int num;// block scope – no linkage
. . .
}