静态变量的内存映射

时间:2014-12-05 08:51:47

标签: c memory-management static

来源:

func_1()
{
    static int i = 10;
    printf("%s : %d\n", __func__, i);
}

func_2()
{
    static int i = 20;
    printf("%s : %d\n", __func__, i);
}

main() {
    static int i = 30;
    func_1();
    func_2();
    printf("%s : %d\n", __func__, i);
}

输出:

func_1 : 10
func_2 : 20
main : 30

编译器如何根据函数区分数据段中的变量?

5 个答案:

答案 0 :(得分:2)

名称i只是每个函数范围的本地,而每个这样的变量都存储在自己的区域中。编译器生成代码,以便从不同的内存地址加载每个代码。

答案 1 :(得分:1)

编译器可能有多种方法来处理这个问题,但这里有一个选项:

  • 逐个编译功能
  • 每当遇到静态变量声明时,请在数据部分中分配新条目
  • 每当遇到静态变量引用时,请将其替换为新条目的地址

如果你考虑一下,这个方法也可以应用于非静态局部变量(改为使用堆栈)。

当然,对于非静态局部变量,地址的完整转换只会在运行时发生。

但概念是相同的 - 一旦编译了函数,其变量的名称就毫无意义。

答案 2 :(得分:0)

这与变量的范围完全相关。这里,三个i是三个独立的变量,每个变量都有自己的范围,在它定义的特定函数中。

func_1 : 10是正确的,因为ifunc_1()是本地的。{/ p>

func_1()
{
    static int i = 10;
    printf("%s : %d\n", __func__, i);
}

func_2 : 20也是正确的,因为ifunc_2()是本地的。{/ p>

func_2()
{
    static int i = 20;
    printf("%s : %d\n", __func__, i);
}

main : 30也是正确的,因为imain()的当地人。

旁注:

  1. 如果您因为static修饰符进行思考,则所有变量都将作为单个变量进行操作,然后您不会遇到多个定义错误? : - )
  2. 如果localglobal变量具有相同的名称,则local变量将被该函数优先使用。

答案 3 :(得分:0)

静态变量的作用域是定义它的块的本地,但它保留了函数调用之间的值。在您的情况下,变量i有3个实例,它们彼此不同。它们中的每一个都存储在不同的存储位置。

答案 4 :(得分:0)

正如@Blagovest Buyukliev所提到的,每个函数中的每个i都是不同的,并且仅在该函数内。编译后代码不知道变量名称,而只是引用适当的位置/内存地址。

因此,如果您稍微更改代码以打印i地址,您会发现每个i都有不同的地址。

func_1()
{
    static int i = 10;
    printf("%s : %d, %p\n", __func__, i, &i);
}

func_2()
{
    static int i = 20;
    printf("%s : %d, %p\n", __func__, i, &i);
}

main() {
    static int i = 30;
    func_1();
    func_2();
    printf("%s : %d, %p\n", __func__, i, &i);
}

示例输出

func_1 : 10, 0x601028
func_2 : 20, 0x601024
main : 30, 0x601020