美文网首页
C中全局变量和static变量的存储与初始化

C中全局变量和static变量的存储与初始化

作者: 丹丘生___ | 来源:发表于2018-08-08 15:31 被阅读0次

目标文件、可执行程序及其他二进制文件以ELF格式存储在磁盘中,该文件有两个重要的段(section),即代码段和数据段。
数据段又分为:.data 段 和 .bss段,其中.data段存储已初始化的全局变量和静态变量,.bss 段存储未初始化的全局变量。

在C中,凡是在任何代码块之外声明的变量总是存储于静态内存中,也就是不属于堆栈的内存,这类变量称为静态(static)变量。——C和指针(p43)

这句话中有两个概念需要搞清楚:

  • 静态内存:指的是前文所述的数据段(.data 段 和 .bss段),不包括堆栈。
  • 静态(static)变量:没有static关键字的变量也可以是静态变量,关键是存储于静态内存中。实际上,当static关键字用于不同上下文环境时,具有不同的意思。
    同时,我们还知道,静态变量在程序运行之前被创建,其分为两种:已初始化的 和 未初始化的。
    • 已初始化的包括:static变量 (这里不能称其为静态变量)、 已初始化的全局变量;static变量是默认zero-initialization的,所以就算未显示初始化,也会被zero-initialization; 全局变量 <=字面值(或常量),即赋予字面值时会在编译阶段就被初始化,如:int g_var = 4;
    • 未初始化的:即未初始化的全局变量。
      如前文所述,前者存储于.data段,后者存储于.bss段。且前者的初始化是在编译阶段就完成的,后者的初始化时刻不一定,我们在后文中讨论。但两者的共同点是,都是在运行前创建的。

这时,我们也许想问,运行前是如何创建静态变量的?

我们知道,编译-汇编后生成二进制目标文件(ELF格式),虽然还不是最终的可执行文件,但已经有了代码段和数据段,而此时数据段中的.data段中已经有了‘已初始化的静态变量’的磁盘存储空间,并被填充了初始化值,在进程加载时直接被映射至内存空间中。

而.bss段实际上未占据任何磁盘存储空间,也就是徒有其名,无有其实,只是在ELF的section header table 中记录其应该分配到的磁盘存储空间,而直到可执行程序被加载到内存中时,加载器将依据.bss段的section header中的信息,在内存中为其分配空间。

总结来说就是,运行前创建分为两种:编译时创建——>加载时映射至内存;加载时创建。


此时,我们仍有疑惑,静态变量的创建肯定是在运行前了,那么未初始化变量的初始化到底是在什么时候进行的?

有三个猜测:

  • 链接时?前文中讲,直至进程加载至内存时才分配空间,自然无谈初始化。
  • 加载进程至内存时

(C和指针)在静态变量的初始化中,我们可以把可执行文件想要初始化的值放在当程序执行时变量将会使用的位置(注:实际上就是磁盘文件.data 段),当可执行文件载入到内存时,这个已经保存了正确初始值的位置将赋值给那个变量……如果不显式地指定其初始值,静态变量将初始化为0。

这段话说的比较晦涩,因为它不想引入过多程序装载过程的知识。但我们也可以借此判断,未初始化的全局变量实际上和static一样会被初始化为0,只不过它是在可执行文件载入到内存时发生的。

  • 运行时,所谓运行时初始化,即动态初始化(dynamic-initialization),然而C与C++不同,静态变量不支持动态初始化。所以运行时也是不可能的。
//in C
int x = 5;
static y = x; //error

//in C++
int x = 5;
static y = x; //correct

最终总结:
在C中,静态变量,即全局变量和static变量,是在程序运行前创建的,其中已初始化的全局变量和static变量在编译汇编成目标文件时,初始值就已经保存在磁盘的.data段了,进程加载时将其映射到内存空间即可;
未初始化的全局变量需要进程加载时真正的为.bss段分配内存空间,并赋值为0。静态变量的创建和初始化都是在运行前完成的,切记C中不能动态初始化,这一点与C++不同。

相关文章

  • static

    c的static 全局变量 定义初始化最好在.c文件c++类的static成员变量在.h class中只是声明

  • C中全局变量和static变量的存储与初始化

    目标文件、可执行程序及其他二进制文件以ELF格式存储在磁盘中,该文件有两个重要的段(section),即代码段和数...

  • 关于static关键字的个人总结

    1,static全局变量和普通全局变量的区别:static全局变量只初始化一次,防止在其他文件单元引用 2,sta...

  • c---全局变量和静态变量

    全局变量与静态变量 static 声明的变量在C语言中有两方面的特征: 1.变量被放在程序的全局存储区中,这样在下...

  • C学习:04内存四区及变量

    变量介绍 C中分全局变量和代码块中的局部变量.static可以修饰全局变量和局部变量以及方法.C中的方法名不同文件...

  • 一、c和c++关键字总结

    c和c++基础 一、static 1、面向过程时 1)数据持久化(包括全局变量和局部变量)2)初始化为03)作用域...

  • Java Map的初始化

    一、前言 static变量的初始化 类变量有点C语言的全局变量的味道,所以一般在单例或者真的只想维护一个全局变量的...

  • 你真的理解static吗?

    static修饰的全局变量与普通的全局变量的区别static修饰的局部变量和普通局部变量的区别static修饰的函...

  • c 静态全局变量

    static 与 全局变量当一个进程的全局变量被声明为static之后,它的中文名叫静态全局变量。静态全局变量和其...

  • static和extern关键字

    static和extern对变量的作用 C语言里的变量分两种:全局变量和局部变量。全局变量又分为外部全局变量和内部...

网友评论

      本文标题:C中全局变量和static变量的存储与初始化

      本文链接:https://www.haomeiwen.com/subject/zqcxbftx.html