c - 在函数后声明全局变量
问题描述
既然我们在这个变量声明之后调用这个函数,为什么我们需要在函数定义和声明之前声明全局变量?不是编译器逐行读取的吗?我的意思是在调用函数时编译器应该知道什么是 x。
void function()
{
x += 3
}
int x = 3;
int main(void)
{
function();
return 0;
}
还有一个问题。我知道我们可以在 main 函数之后定义函数,前提是我们在 main 之前声明了这个函数。那么main函数是如何在main函数之后看到这些函数的呢?编译器是否首先读取整个文件然后运行 main() 或某事?
解决方案
你可以这样思考编译器的工作;它逐个标记(不完全是逐行)读取源文件标记,当读取到足够的标记时,它会输出翻译。它重复这一点,直到源文件(正确)完成:编译器的工作完成。
对于编译器读取的每个标记,它需要知道标记代表什么。如果它不知道,则会产生错误。
所以,在编译你的函数时
void function()
{
x += 3
}
它遇到一个“x”但不知道它代表什么(一个整数?一个浮点数?别的东西?)。-错误-。
为什么我们需要在函数定义和声明之前声明全局变量
声明和定义是两个不同的东西。编译器需要声明才能知道如何管理标识符;真正的定义可以在其他地方,甚至在另一个源(或已经编译的)文件中。
还有一个问题。我知道我们可以在 main 函数之后定义函数,前提是我们在 main 之前声明了这个函数。那么main函数是如何在main函数之后看到这些函数的呢?编译器是否首先读取整个文件然后运行 main() 或某事?
如前所述,编译器所需要的只是一个声明,因此它可以输出正确的(对象)代码。如果先声明 function(),然后定义 main(),再定义 function(),编译器就有足够的能力生成正确的输出,这将由 main() 的代码和 function() 的代码组成(我们可以说“在这个命令”)。下一步,链接器将注意连接这两个函数。
function() 的定义也可能不存在:编译器仍然会为 main() 生成正确的代码;链接器反而会抱怨,除非你告诉它在哪里可以找到 function() 的定义/实现。
另请注意,定义也是声明。因此,如果您在源代码中声明了 function(),然后声明了 main(),则不需要前向声明。
在我读到的评论中,也许您将解释器与编译器混淆了——如果您尝试将 Python 与 C 进行比较,这是真的:非常不同的野兽。一个很大的区别是编译器与解释器,编译器生成数据(目标代码)但不链接它(也不运行它)。相反,解释器是编译器+链接器+运行时,全部打包在一起。通常,编译器生成的代码比等效的解释程序要快得多,但要做到这一点,它需要准确的信息(精确的类型和声明),而且通常(总是?)通用性较差。解释器通常更通用,但它不能利用一个好的编译器可以做的所有优化。
推荐阅读
- git - 如何重置先前提交中的所有更改并将其与实际合并?
- java - 热敏打印机自动剪切未完成的收据,留下最后两行
- spring - 从第三方 Java 应用程序启动 Spring Boot 应用程序
- php - 计算存储在树状数组中的类别的费用
- html - 输入、下拉菜单和按钮绝对不起作用
- php - Wordpress 添加到购物车按钮自定义
- git - git checkout 花费太长时间“检查子模块”
- amazon-web-services - AWS CloudFront CNAME 和分发域名关系不明确
- codenameone - 在代号一中格式化本地化日期
- vb.net - VB 2019 - 从另一个表填充 DataGridView 中的未绑定列