【问题标题】:Declare global variable after function在函数后声明全局变量
【发布时间】:2020-04-14 14:24:58
【问题描述】:

既然我们在这个变量声明之后调用这个函数,为什么我们需要在函数定义和声明之前声明全局变量?不是编译器逐行读取吗?我的意思是在调用函数时编译器应该知道 x 是什么。

void function()
{
    x += 3
}


int x = 3;

int main(void)
{
   function();
   return 0;
}

还有一个问题。我知道我们可以在 main 函数之后定义函数,前提是我们在 main 之前声明了这个函数。那么main函数是如何在main函数之后看到这些函数的呢?编译器是否首先读取整个文件然后运行 ​​main() 或某事?

【问题讨论】:

  • 您是否混淆了编译器和解释器?
  • 你回答了你自己的问题。编译器逐行读取。如果遇到x,并且没有被声明或定义,就会报错。
  • 如果编译器遇到未定义的东西,编译器必须通过前向声明知道它,否则就是错误。
  • 您将 C 与一些脚本语言混为一谈。变量不是在运行时而是在编译时定义的。函数function 必须是可编译的,无需了解调用者的任何信息或之后可能解析的任何代码。
  • @Gerhardh 我是这么认为的,在 Python 中这行得通……我感到很困惑

标签: c


【解决方案1】:

你可以这样思考编译器的工作;它逐个标记(不完全是逐行)读取源文件标记,当读取到足够的标记时,它会输出翻译。它重复这一点,直到源文件(正确)完成:编译器的工作完成。

对于编译器读取的每个标记,它需要知道标记代表什么。如果不知道,则会产生错误。

所以,在编译你的函数时

void function()
{
    x += 3
}

它遇到一个“x”,但不知道它代表什么(一个整数?一个浮点数?别的东西?)。 -错误-。

为什么要在函数定义和声明之前声明全局变量

声明定义是两个不同的东西。编译器需要声明才能知道如何管理标识符;真正的定义可以在其他地方,甚至在另一个源(或已经编译的)文件中。

还有一个问题。我知道我们可以在 main 函数之后定义函数,前提是我们在 main 之前声明了这个函数。那么main函数是如何在main函数之后看到这些函数的呢?编译器是先读取整个文件,然后运行 ​​main() 还是什么?

如前所述,编译器所需要的只是一个声明,因此它可以输出正确的 (object) 代码。如果先声明 function(),然后定义 main(),再定义 function(),编译器就有足够的能力生成正确的输出,这将由 main() 的代码和 function() 的代码组成(我们可以说“在这个命令”)。下一步,链接器将负责连接这两个函数。

function() 的定义也可能不存在:编译器仍然会为 main() 生成正确的代码;链接器反而会抱怨,除非你告诉它在哪里可以找到 function() 的定义/实现。

还要注意,定义也是声明。因此,如果您在源代码中声明了 function(),然后声明了 main(),则不需要前向声明。

在我读到的 cmets 中,您可能将解释器与编译器混淆了 - 如果您尝试将 Python 与 C 进行比较,这是真的:非常不同的野兽。一个很大的区别是编译器与解释器,编译器生成数据(目标代码)但不链接它(也不运行它)。相反,解释器是编译器+链接器+运行时,全部打包在一起。通常,编译器生成的代码比等效的解释程序要快得多,但要做到这一点,它需要准确的信息(精确的类型和声明),而且通常(总是?)通用性较差。解释器通常更通用,但它不能利用好的编译器可以做的所有优化。

【讨论】:

    【解决方案2】:

    为什么我们需要在定义函数之前声明全局变量 并声明,因为我们在此之后调用此变量函数 声明?

    c 语言是一种严格类型的语言。当编译器处理一个标识符时,它需要确定其类型以生成正确的目标代码。

    函数中使用的全局变量不必在函数定义之前准确声明。但在任何情况下,它都应在函数中使用之前声明。

    这是一个演示程序。

    #include <stdio.h>
    
    void function( void )
    {
        extern int x;    
        x += 3;
    }
    
    int x = 3;
    
    int main( void ) 
    {
        function();
        printf( "x = %d\n",  x );
    
    }
    

    程序输出是

    x = 6
    

    这里函数内声明的变量x指的是函数后定义的全局变量x。

    那么在main函数之后main函数是如何看到这些函数的呢? 编译器是否首先读取整个文件然后运行 ​​main() 或 某事?

    C 是一种编译语言。它不运行程序。它生成目标代码,然后通过链接器进行一些处理后可以运行。

    在使用函数的地方,编译器需要的是函数的类型来检查函数是否被正确使用。如果函数是内联函数,那么它可以用它的调用代替函数体。当翻译单元中的内联定义已知时,它可以重建目标代码。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-05-11
      • 1970-01-01
      • 2017-03-01
      • 2014-01-17
      • 1970-01-01
      • 2018-09-28
      • 2015-12-14
      相关资源
      最近更新 更多