首页 > 解决方案 > 在函数后声明全局变量

问题描述

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

void function()
{
    x += 3
}


int x = 3;

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

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

标签: c

解决方案


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

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

所以,在编译你的函数时

void function()
{
    x += 3
}

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

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

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

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

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

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

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

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


推荐阅读