来源:
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
编译器如何根据函数区分数据段中的变量?
答案 0 :(得分:2)
名称i
只是每个函数范围的本地,而每个这样的变量都存储在自己的区域中。编译器生成代码,以便从不同的内存地址加载每个代码。
答案 1 :(得分:1)
编译器可能有多种方法来处理这个问题,但这里有一个选项:
如果你考虑一下,这个方法也可以应用于非静态局部变量(改为使用堆栈)。
当然,对于非静态局部变量,地址的完整转换只会在运行时发生。
但概念是相同的 - 一旦编译了函数,其变量的名称就毫无意义。
答案 2 :(得分:0)
这与变量的范围完全相关。这里,三个i
是三个独立的变量,每个变量都有自己的范围,在它定义的特定函数中。
func_1 : 10
是正确的,因为i
在func_1()
是本地的。{/ p>
func_1()
{
static int i = 10;
printf("%s : %d\n", __func__, i);
}
func_2 : 20
也是正确的,因为i
在func_2()
是本地的。{/ p>
func_2()
{
static int i = 20;
printf("%s : %d\n", __func__, i);
}
main : 30
也是正确的,因为i
是main()
的当地人。
旁注:
static
修饰符进行思考,则所有变量都将作为单个变量进行操作,然后您不会遇到多个定义错误? : - )local
和global
变量具有相同的名称,则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