【问题标题】:Is Declaration of Variable in C Limited to Extern Keyword Alone Vs DefinitionC中的变量声明是否仅限于外部关键字与定义
【发布时间】:2018-10-24 12:29:08
【问题描述】:

我怀疑在寻求声明和定义之间的差异时我缺少一些东西,我找到了链接 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 = %d\n", 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 = %d\n", x, y); 
        } 

        // This statement accesses only outer block's variables 
        printf("x = %d, y = %d\n", 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 = %d\n", 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 = %d\n", x, y); 
        } 

        // This statement accesses only outer block's variables 
        printf("x = %d, y = %d\n", x, y); 
    }
} 
return 0; 
} 

结果是

x = 10, y = 20
x = 11, y = 41
x = 11, y = 41

我的朋友告诉我这是因为我们声明了一个新的 y,它是第一个代码中的块本地的,而不是第二种情况,我不明白为什么,因为我们只是第二次写变量前面的数据类型,是不是写数据类型我们预留了一个新的内存空间,又创建了一个新的变量,请解释一下。

如果我在链接上查看有关 Stackoverflow 的另一篇文章 What is the difference between a definition and a declaration?

我看到,每当我们说我们声明一个变量时,变量前面都有 extern 关键字,我说的是与 C 语言而不是任何其他语言严格相关。

所以我们可以概括为以extern关键字开头的变量声明。

我知道我的英语可能很糟糕,你很难理解,请多多包涵。

【问题讨论】:

  • 如果您正在学习 C,那么阅读 C++ 答案并没有多大帮助。

标签: c


【解决方案1】:
    { 
        // 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 是对现有变量的赋值。

【讨论】:

  • 为什么我在两个代码 int y = 40 中得到不同的结果,也就像再次为变量 y 分配一个新值。
  • 就像我说的,你只是分配给y;你只是在改变它的价值。没有新的变量。这就是为什么你会看到外部printf 的变化。
  • 如果 int y 只是一个声明,那么为什么按照stackoverflow.com/questions/1410563/… int y;是定义而不是声明
  • 在谈到局部变量时,最好使用单词definition 而不是declaration。没有定义它是不可能declare局部变量的。
【解决方案2】:

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;

现在,对于您的第一个代码示例...

首先,您声明并实例化两个变量,xy

int x = 10;
int y = 20;

然后打印它们,导致打印x = 10, y = 20。这是有道理的,因为x 是 10,y 是 20。

然后,您使用大括号创建一个新范围并声明一个名为y 的新变量。由于此变量与高于它的范围内的变量具有相同的名称,因此它隐藏名为 y 的外部变量,直到退出此范围。

{
    int y = 40;

thisy的任何更改都不会影响外部y,并且在thisy的范围之前无法访问外部y已退出。

然后增加xy,然后打印结果。由于上述行为,x = 11, y = 41 被打印出来。

打印上述字符串后,代码退出当前作用域。因此,外部的y 不再隐藏,现在可以访问了。

最后,您再次打印xyx 是 11,因为它之前增加了,但是外部的 y 没有增加,因此打印了 x = 11, y = 20


像您在第二个代码示例中所做的那样,将int y = 40 替换为y = 40 会导致只有一个y 变量被声明和实例化。因此,y 在第三个 printf() 语句中最终为 41。

【讨论】:

  • 非常感谢 Tau 的精彩解释.. 还有一个场景,如果我在 main 之外声明并初始化 int y = 5 会怎样,那么它将像一个全局那样
  • ` int y=5; int main() { { int x = 10;整数 y = 20; { printf("x = %d, y = %d\n", x, y); { int y; x++;是++; printf("x = %d, y = %d\n", x, y); } printf("x = %d, y = %d\n", x, y); } } 返回 0; } ` 我得到以下结果 ` x = 10, y = 20 x = 11, y = 32765 x = 11, y = 20 `
  • @beastboy 确保在使用之前给内部 y 一个值。否则,您将得到 Undefined Behaviour,因为内部 y 在您使用之前会在其中包含垃圾数据。
  • 是的,如果您在 main() 之外声明和实例化 y,那么它将是全局的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-03
  • 2015-06-30
相关资源
最近更新 更多