zoukankan      html  css  js  c++  java
  • 【总结】【变量】变量的存储域 [转]

    http://blog.csdn.net/chgaowei/article/details/5340796

    1.1 变量存储域

    1.1.1 一个示例

    pang123hui首先提供了一个网上流传的学习代码示例:

    int a = 0; //全局区 

    void main() 

    {

    int b; //栈 

    char s[] = “abc”; //s在栈,abc在文字常量区 

    char *p1,*p2; //栈 

    char *p3 = "123456"; //123456在常量区,p3在栈上 

    static int c =0; //全局区 

    p1 = (char *)malloc(10); //p1在栈,分配的10字节在堆 

    p2 = (char *)malloc(20); //p2在栈,分配的20字节在堆 

    strcpy(p1, "123456"); //123456放在常量区 

    }

    这个代码示例中出现了“全局区”,“栈”,“文字常量区”,“堆”等词语。为了统一,我们使用《C专家编程》中的说法:堆栈段,BSS段,数据段,文本段。

    各个段的作用如下:

    1、 文本段:包含程序的指令,它在程序的执行过程中一般不会改变。

    2、 数据段:包含了经过初始化的全局变量和静态变量,以及他们的值。

    3、 BSS段:包含未经初始化的全局变量和静态变量。

    4、 堆栈段:包含了函数内部声明的局部变量。

    当然,上面段的作用不仅于此,具体的作用会在下面的知识点中介绍。

    1.1.2 通过代码测试变量的存储位置

    Linux下可以通过系统命令“size”查看可以执行程序各个段的大小。但是,可执行程序中的段结构和运行中程序在内存中的段结构并不完全相同,但是有一定的映射关系。具体如下图所示(图片信息来自《C专家编程》):

    wps_clip_image-696

    下面通过代码示例和“size”来研究变量的存储区域。

    test.c

    int main()

    {

    return 1;

    }

    编译,并且查看可执行程序各个段的大小:

    wps_clip_image-779

    更改test.c:

    int g_data;

    int main()

    {

    return 1;

    }

    编译,并且查看可执行程序各个段的大小:

    wps_clip_image-849

    可以发现,文本段,数据段都没有发送变化,而BSS段增加了4个字节。

    结论1:未初始化的全局变量保存在BSS段中

    继续:

    int g_data = 1;

    int main()

    {

    return 1;

    }

    编译:

    wps_clip_image-958

    可以发现,BSS段和文本段相同,而数据段增加了4个字节。

    结论2:经过初始化的全局变量保存在数据段中

    继续:

    int main()

    {

    static int g_data;

    return 1;

    }

    编译:

    wps_clip_image-1066

    可以发现,文本段,数据段都没有发送变化,而BSS段增加了4个字节。

    结论3:未初始化的静态变量保存在BSS段中

    继续:

    int main()

    {

    static int g_data = 1;

    return 1;

    }

    编译:

    wps_clip_image-1183

    可以发现,BSS段和文本段相同,而数据段增加了4个字节。

    结论4:经过初始化的静态变量保存在数据段中

    继续:

    int main()

    {

    int i_data = 1;

    return 1;

    }

    编译:

    wps_clip_image-1288

    可以发现,BSS段和和数据段相同,而文本段增加了16个字节。局部变量会在执行的时候在堆栈段中生成,函数执行完毕后释放。

    结论5:函数内部声明的局部变量保存在堆栈段中

    继续:

    const int g_data = 1;

    int main()

    {

    return 1;

    }

    编译:

    wps_clip_image-1430

    把全局变量定义为“const”后,也许你会感到奇怪,怎么BSS段和数据段都没有发生变化,而文本段却增加了4个字节。

    结论6:const修饰的全局变量保存在文本段中

    那么,const的局部变量?

    继续:

    int main()

    {

    const int i_data = 1;

    return 1;

    }

    编译:

    wps_clip_image-1587

    结论7:const修饰的局部变量保存在堆栈段中

    继续:

    char *pstr = "";

    int main()

    {

    return 1;

    }

    编译:

    wps_clip_image-1666

    在做一下更改:

    char *pstr = "123456789";

    int main()

    {

    return 1;

    }

    编译:

    wps_clip_image-1733

    可以发现,前后数据段和BSS段大小均未发生变化,而文本段增加了9个字节。

    结论8:字符串常量保存在文本段中

    1.1.3 结论

    1、 经过初始化的全局变量和静态变量保存在数据段中。

    2、 未经初始化的全局变量和静态变量保存在BSS段。

    3、 函数内部声明的局部变量保存在堆栈段中。

    4、 const修饰的全局变量保存在文本段中,const修饰的局部变量保存在堆栈段中。

    5、 字符串常量保存在文本段中。

    1.1.4 扩展阅读

    《C专家编程》第6章——详细介绍各个段的作用。

  • 相关阅读:
    SourceTree使用教程(六)--回滚版本到某次提交
    SourceTree使用教程(四)---冲突解决
    Git 分支合并后回退的几种情况分析
    HTTP认证之基本认证——Basic(二) _
    C#3.0中自动属性和对象初始化器
    C# 3.0新特征之创建和初始化集合对象
    SQL 用多个条件进行排序;以及根据一个条件的多个值,进行排序
    如何修改 .NET Core Kestrel 下的端口
    存储过程
    mysql临时表用法分析【查询结果可存在临时表中】
  • 原文地址:https://www.cnblogs.com/buxianghe/p/3047576.html
Copyright © 2011-2022 走看看