C语言 静态变量的初始化

Posted 庖丁解牛

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言 静态变量的初始化相关的知识,希望对你有一定的参考价值。

C语言静态变量的初始化,c程序内存分布

一、C程序的内存分布

C程序由下面5部分组成

正文段(.text):通常是指用来存放程序执行代码的一块内存区域。这部分区域的大小在程序运行前就已经确定,并且内存区域属于只读。在代码段中,也有可能包含一些只读的常量,例如字符串常量等。

初始化数据段(.data):通常是指用来存放程序中已初始化的全局变量的一块区域,在进程运行时静态分配。

未初始化数据段(.bss):存放包含程序中未初始化的全局变量和static变量。BBS是英文block started by symbol的简称。由于未初始化,因此默认值为0。为了节省磁盘空间,程序中并不需要保存这些变量的映像,只将所需要的BSS段大小记录在程序文件中,但BSS段并不占据任何空间,在进程运行时静态分配

栈(stack):按内存地址由高到低方向生长,其最大大小由编译时确定,自动变量以及每次函数调用时所需保存的信息都存放在此段中。每次函数调用时,其返回地址以及调用者的环境信息(如某些机器寄存器的值)都存放在栈中。然后,最近被调用的函数在栈上为其自动和临时变量分配存储空间。通过这种方式使用栈,C递归函数可以工作。递归函数每次调用自身时,就用一个新的栈帧,因此一次函数调用实例中的变量集不会影响另一次函数调用实例中的变量。

堆(heap):自由申请的空间,按内存地址由低到高方向生长,其大小由系统内存/虚拟内存上限决定。通常在堆中进行动态存储分配。由于历史上形成的惯例,堆位于未初始化数据段和栈之间。
每个线程都会有自己的栈,但是堆空间是共用的。

备注:.text段和.data段都在可执行文件中,由系统从可执行文件中加载;而.bss段不在可执行文件中,由系统初始化。

c程序内存分布图

二、静态变量(包括全局变量、静态全局变量、静态局部变量)

1) 内存中的位置:静态存储区(静态存储区在整个程序运行期间都存在)
2) 数据存储:
a) 已初始化的存储在数据区中的已初始化变量区
b) 未初始化的存储在数据区中的未初始化变量区(未经初始化的全局静态变量会被程序自动初始化为0)
3) 生命周期:静态变量的生命周期是从所处模块装载到所处模块卸载

三、部变量和静态变量的初始化有何不同

未初始化的局部变量位于栈中,它的位置是不确定的,因此其值也是不确定的。
静态变量的地址是确定的,并且存放在了数据段,而程序在运行之前,未初始化数据段的内容可以很方便地统一被初始化为0

/* C语言静态变量的初始化 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

static int m;

void test()

    static int n = 99;

    // 打印 m is 0, n is 99
    printf("m is %d, n is %d\\n", m, n);


int main()

    test();
    return 0;

 

C语言之变量作用域

参考技术A 全局变量:作用域整个工程,在使用的地方通过extern声明即可,存放于全局数据区,占用静态存储单元。

局部变量:作用于函数方法体内,函数执行结束就释放,存放于栈区。

全局静态变量:作用于当前类,在外部类不可使用,除非使用#include引入头文件,存放于全局数据区。

局部静态变量:作用于函数方法体内,函数执行结束不释放,存放于全局数据区。

全局静态存储区:分为 DATA 段和 BSS 段。DATA 段(全局初始化区)存放初始化的全局变量和静态变量;BSS 段(全局未初始化区)存放未初始化的全局变量和静态变量。程序运行结束时自动释放。其中BBS段在程序执行之前会被系统自动清0,所以未初始化的全局变量和静态变量在程序执行之前已经为0。存储在静态数据区的变量会在程序刚开始运行时就完成初始化,也是唯一的一次初始化。

静态存储变量的优势:

优势: 可以节省内存,因为它是所有对象所公有的,因此,对多个对象来说,静态数据成员只存储一处,供所有对象共用。静态数据成员的值对每个对象都是一样,但它的值是可以更新的。只要对静态数据成员的值更新一次,保证所有对象存取更新后的相同的值,这样可以提高时间效率。

关于static

(1)在修饰变量的时候,static 修饰的静态局部变量只执行初始化一次,而且延长了局部变量的生命周期,直到程序运行结束以后才释放。

(2)static 修饰全局变量的时候,这个全局变量只能在本文件中访问,不能在其它文件中访问,即便是 extern 外部声明也不可以。

(3)static 修饰一个函数,则这个函数的只能在本文件中调用,不能被其他文件调用。static 修饰的变量存放在全局数据区的静态变量区,包括全局静态变量和局部静态变量,都在全局数据区分配内存。初始化的时候自动初始化为 0。

(4)不想被释放的时候,可以使用static修饰。比如修饰函数中存放在栈空间的数组。如果不想让这个数组在函数调用结束释放可以使用 static 修饰。

(5)考虑到数据安全性(当程序想要使用全局变量的时候应该先考虑使用 static)。

以上是关于C语言 静态变量的初始化的主要内容,如果未能解决你的问题,请参考以下文章

联合变量宏-C语言

请问C中结构体变量为全局变量或静态变量时才能初始化么?

C语言局部变量全局变量,局部静态变量,全局静态变量,extern,static的区别

c语言的auto和static类型变量

c语言中的静态存储变量是存储在哪里的,一般啥时候用

C语言知识:函数详解(变量的作用域,全局变量,静态变量)