我对以下代码有疑问
#include<stdio.h>
int i=6;
int main()
{
int i=4;
{
extern int i;
printf("%d",i); //prints 6
}
printf("%d",i); //prints 4
}
我们知道extern
关键字表示编译器,变量位于外部。所以问题是extern
关键字访问全局i
变量而不是主函数内的i
变量的原因?我认为必定存在矛盾,因为两个变量都可用作内部括号作为全局变量。那么extern关键字访问函数外部的变量,或者它也访问大括号外的变量。
答案 0 :(得分:5)
extern
并不意味着在当前范围之外,它意味着具有外部链接的对象。自动变量永远不会有外部链接,因此您的声明extern int i
不可能引用它。因此它隐藏了它,就像隐藏全局的自动变量一样。
答案 1 :(得分:3)
在打印6的printf
之前,您要求编译器使用i
之后定义的#include
。然后,右大括号告诉编译器extern
不再有效,因此它使用i
设置为4的范围。
答案 2 :(得分:1)
int i = 4 不是全局变量,如果您尝试访问另一个函数中main的 var i ,编译器将抛出 var的错误我是未宣布的。这段代码说明了这一点。
void func() {
printf("i is %d\n",i);
}
main() {
int i=10;
func();
}
而main之外的i是全局变量,您可以在所有函数中访问它。
答案 3 :(得分:1)
我想你在问你是否正确认为extern int i
声明会导致第一个printf
解析i
到4
因为int i=4
extern
1}}语句位于声明extern的作用域的父作用域中。
答案是否定的,因此你所看到的行为。函数中的{{1}}声明用于声明外部变量的存在,并且不会解析为 local 变量(声明为 函数内部。)
答案 4 :(得分:1)
/ * Ed Heal所说的* / 然而,我认为最好用另外的例子来说明它。我修改了你的例子做了一点。代码中的注释充分说明了它:
#include <stdio.h>
int i = 6;
int main(void)
{
int i = 4;
printf("%d\n", i); /* prints 4 */
{
extern int i; /* this i is now "current". */
printf("%d\n", i); /* prints 6 */
{
int *x = &i; /* Save the address of the "old" i,
* before making a new one. */
int i = 32; /* one more i. Becomes the "current" i.*/
printf("%d\n", i); /* prints 32 */
printf("%d\n", *x); /* prints 6 - "old" i through a pointer.*/
}
/* The "previous" i goes out of scope.
* That extern one is "current" again. */
printf("%d\n", i); /* prints 6 again */
}
/* That extern i goes out of scope.
* The only remaining i is now "current". */
printf("%d\n", i); /* prints 4 again */
return 0;
}