如果没有参考价值,它会永久存在吗?

时间:2018-10-18 13:31:00

标签: c

假设以下最少代码:

#include <stdio.h>
char character = 'c';
int main (void)
{
    char character = 'b';
    printf("The current value of head is %c", character);
}

我在character中改写了main
那么c怎么了?它会自动销毁还是永久保留在内存中?

这句话引起了我的兴趣:“ C中的变量不过是命名的内存块而已。”

8 个答案:

答案 0 :(得分:25)

shadowing”全局character变量对main函数隐藏了该变量,但它仍将是程序的一部分。

如果将character变量声明为static,则编译器可能会警告不要使用character变量,并且character将被优化。

但是,character变量未声明为static;编译器将假设character变量可以从外部访问,并将character变量保留在内存中。

编辑

如@Deduplicator所述,如果允许,链接器的优化和设置可以从最终可执行文件中忽略该变量。但是,这是一个边缘情况,不会“自动”发生。

答案 1 :(得分:13)

您有两个分别名为character的变量:一个在文件作用域中设置为'c',其生存期是程序的生存期,在main中一个变量设置为'b',其生存期是它的范围。

charactermain的定义在文件范围内屏蔽,因此只能访问后者。

答案 2 :(得分:6)

补充其他答案:

尝试一下,您将了解:

#include <stdio.h>

char character = 'c';

void Check()
{
  printf("Check: c = %c\n", character);
}

int main(void)
{
  char character = 'b';
  printf("The current value of head is %c\n", character);
  Check();
}

答案 3 :(得分:5)

它将继续存在(直到程序死亡,就像任何静态存储变量一样),您仍然可以使用它:

#include <stdio.h>
char character = 'c';
int main (void)
{
    char character = 'b';
    printf("The current value of head is '%c'\n", character);
    {
        extern char character;
        //in this scope, overrides the local `character` with 
        //the global (extern?) one
        printf("The current value of head is '%c'\n", character);
    }
    printf("The current value of head is '%c'\n", character);
}
/*prints:
The current value of head is 'b'
The current value of head is 'c'
The current value of head is 'b'
*/

对于static全局变量,本地extern声明不能可靠/方便地工作,尽管您仍然可以通过指针或单独的函数来访问它们。


( 为什么static char character='c'; int main(){ char character='b'; { extern char character; } }与全局static不可靠?

6.2.2p4似乎也想使其适用于静态变量,但是措辞含糊(先前的声明没有链接,而另一个声明具有静态/外部链接,那么现在怎么办?)。

6.2.2p4

  

对于在存储类说明符extern中声明的标识符   可以看到该标识符的先前声明的范围,31)   如果先前声明指定了内部或外部链接,则   后面声明中标识符的链接与   事先声明中指定的链接。如果没有事先声明   可见,或者如果先前的声明未指定任何链接,则   标识符具有外部链接。

我的clang 6.0.0使用static char character='b';接受它,但我的gcc 7.3.0不接受。

感谢Eric Postpischil指出了static也可以使用的不确定性。 )

答案 4 :(得分:3)

character中声明main之后,在该函数中对character的任何引用都指向那个,而不是全局范围内的那个。我们称之为 shadowing

对于内存的影响,由于该语言采用了 as-if 规则,因此您不能说:编译器可能会优化为

#include <stdio.h>
int main()
{
     printf("The current value of head is b");
}

例如。

答案 5 :(得分:2)

Form1

一切都清楚了。它并没有被破坏,只是被遮盖了。

输出:                                                                                           head的当前值为b
         c

答案 6 :(得分:1)

通常,全局变量将保留。由于您的局部变量仅会遮盖名称,因此不会影响存储。

但是它也可能取决于链接器设置。链接器可以优化未使用的全局变量。

答案 7 :(得分:1)

尽管全局变量从程序执行的开始到结束都存在,但不能自动访问它们。

从文件中定义或声明全局变量的位置开始,直到文件末尾都可以访问全局变量。

如果在函数作用域中定义了一个具有相同名称的变量,则该全局变量将存在,但将不可访问。