这是一个小程序:
#include <iostream>
using namespace std;
int main() {
f();
system("pause");
}
void f() {
static int x = 20 ;
class tester {
public :
tester() {
cout << x ;
}
} x1;
}
Run Code Online (Sandbox Code Playgroud)
我在这里得到的错误是:错误C3861:'f':找不到标识符
如果我将函数f置于main之上,我将获得所需的输出.
为什么会这样?
我被告知程序执行开始于main.据此,代码也应该在第一种情况下运行.
编译器如何开始阅读程序?
我被告知程序执行从main开始.
而这正是重点.
编译器从main,然后看到一个调用f(),到目前为止它没有遇到过(因为它是后来定义的),所以它不知道如何处理它.
如果你想f在main之前放置一个函数原型之后定义,比如
#include <iostream>
using namespace std;
void f(); // <--- This tells the compiler that a function name f will be defined
int main() {
f();
system("pause");
}
void f() {
static int x = 20 ;
class tester {
public :
tester() {
cout << x ;
}
} x1;
}
Run Code Online (Sandbox Code Playgroud)
编译的开始和程序执行的开始是两回事.
执行从main.
编译从文件的开头开始; 编译器不会"跳转"文件以找到所需的部分,但它以线性方式读取输入(我怀疑这与C++语法真正复杂的事实相关).
当编译器在某个时刻解析文件时,它只知道在该点1之前声明/定义的内容.
因此,已经发明了函数原型(以及一般的非定义声明):文件中定义的所有函数的原型都放在文件的开头,通常在#include指令之后或在单独的包含文件中.原型告诉编译器这些函数将在稍后定义,函数签名是什么(即名称,参数,返回值).
原型是作为正常功能制作的,但没有身体,而是用分号2代替.例如,在你的代码中你会写
void f();
Run Code Online (Sandbox Code Playgroud)
之前main.
IIRC对此规则有一些放松,允许编译器"等待"一些声明来使模板魔术工作,但这与此无关.
在原型中也常见的是不写参数的名称,只留下它们的类型(这也可以在函数定义中完成,但除非你有一个不使用的形式参数,否则它没有多大意义) .不过,我更喜欢将参数名称留在那里作为一种文档形式.
| 归档时间: |
|
| 查看次数: |
1917 次 |
| 最近记录: |