我怀疑我缺少一些东西来寻找声明和定义之间的区别,我找到了链接 https://www.geeksforgeeks.org/commonly-asked-c-programming-interview-questions-set-1/它在这里说
// This is only declaration. y is not allocated memory by this statement
extern int y;
// This is both declaration and definition, memory to x is allocated by this statement.
int x;
现在,如果我按照以下代码段进行操作
int main()
{
{
int x = 10;
int y = 20;
{
// The outer block contains declaration of x and y, so
// following statement is valid and prints 10 and 20
printf("x = %d, y = %dn", x, y);
{
// y is declared again, so outer block y is not accessible
// in this block
int y = 40;
x++; // Changes the outer block variable x to 11
y++; // Changes this block's variable y to 41
printf("x = %d, y = %dn", x, y);
}
// This statement accesses only outer block's variables
printf("x = %d, y = %dn", x, y);
}
}
return 0;
}
我会得到以下结果
x = 10, y = 20
x = 11, y = 41
x = 11, y = 20
如果我只将最里面块中的 int y = 40 修改为y = 40,那么代码将看起来像
//int y;
int main()
{
{
int x = 10;
int y = 20;
{
// The outer block contains declaration of x and y, so
// following statement is valid and prints 10 and 20
printf("x = %d, y = %dn", x, y);
{
// y is declared again, so outer block y is not accessible
// in this block
y = 40;
x++; // Changes the outer block variable x to 11
y++; // Changes this block's variable y to 41
printf("x = %d, y = %dn", x, y);
}
// This statement accesses only outer block's variables
printf("x = %d, y = %dn", x, y);
}
}
return 0;
}
结果将是
x = 10, y = 20
x = 11, y = 41
x = 11, y = 41
我的朋友告诉我这是因为我们在第一个代码中声明一个新的y是块的本地的,而在第二种情况下不是,我不明白为什么,因为我们只是第二次在变量前面写数据类型,这是否意味着通过写入数据类型我们保留了一个新的内存空间并创建了一个新变量, 请解释.
如果我在链接上阅读另一篇关于堆栈溢出的文章 定义和声明有什么区别?
我看到每当我们说我们正在声明一个变量时,变量前面都有 extern 关键字,我说的是严格相关的 C 而不是任何其他语言。
因此,我们可以推广到变量声明,前面是 extern 关键字。
我知道我的英语可能不好,你很难理解,请耐心等待。
{
// y is declared again, so outer block y is not accessible
// in this block
y = 40;
你的评论是错误的。 这不是再次宣布y
。它只是分配给它。
相反,它应该说:
// This changes the value of y in the outer block
这是否意味着通过写入数据类型,我们保留了一个新的内存空间并创建了一个新变量
是的。
int y
是新变量的声明。int y = 40
是一个声明和初始化。y = 40
是对现有变量的赋值。
extern int y;
告诉编译器,y
可以在链接到该程序的另一个文件中声明,无论是库、头文件等,如果编译器找到名为y
的全局变量,那么它应该使用其内存地址来声明该文件中声明的y
。 即:
//Look for a global variable called "y" in the included files
//If it is found, use its memory address
extern int y;
现在,对于您的第一个代码示例...
首先,声明并实例化两个变量,x
和y
。
int x = 10;
int y = 20;
然后打印它们,导致打印x = 10, y = 20
。 这是有道理的,因为x
是 10,y
是 20。
然后,使用大括号创建一个新范围,并声明一个名为y
的新变量。 由于此变量与高于它的作用域中的变量同名,因此它会隐藏名为y
的外部变量,直到退出此作用域。
{
int y = 40;
对此y
的任何更改都不会影响外部y
,并且在退出此y
的范围之前无法访问外部y
。
然后递增x
并y
,然后打印结果。 由于上述行为,打印x = 11, y = 41
。
打印上述字符串后,代码退出当前范围。 因此,外部y
不再隐藏,现在可以访问它。
最后,打印x
并再次y
。x
是 11,因为它之前已递增,但外部y
未递增,因此打印x = 11, y = 20
。
像在第二个代码示例中所做的那样,将int y = 40
替换为y = 40
会导致仅声明和实例化一个y
变量。 因此,y
在第三个printf()
语句中最终是 41。