当我偶然发现一些不应该工作的代码时,我正在学习一些非常基本的C ++。它确实!
这是我发现的一个非常简单的版本:
#include <iostream>
using namespace std;
string HelloWorld();
int main(){
cout << HelloWorld();
}
string HelloWorld(){
return "Hello World";
}
为什么这样做?我正在打印尚未声明的内容。它什么都不打印。
答案 0 :(得分:4)
这是完全正确的。
string HelloWorld();
这里你告诉编译器:“嘿,这个名为HelloWorld
的函数存在于某处。它不带参数并返回一个字符串。这就是函数声明。你'重新声明它存在。它特别称为forward declaration。
int main(){
cout << HelloWorld();
}
现在当你在这里调用HelloWorld
时,编译器知道它存在于某处,因为你告诉它它会。
string HelloWorld(){
return "Hello World";
}
这里你实际上是定义这个功能。你告诉编译器:“当我说HelloWorld
存在于某个地方时,这就是我的意思。
编译程序时,它会在几个过程中发生,每个过程都满足要构建的程序的更多要求。最后,并不重要代码所在的位置。如果一切都存在,链接器的作业(不出所料)将所有内容链接在一起,并将main
指向HelloWorld
,即使它位于main
之后C档。
也许你是Python或PHP程序员?
请记住,C与这些语言完全不同,因为C是一种编译语言 - 程序生命周期中存在的每个函数都在构建完成时存在。
答案 1 :(得分:1)
在调用站点,编译器只需要声明。在这种情况下,HelloWorld()
在被调用之前是前向声明的。
链接器的工作是确保引入所有必需的定义。如果必须在使用时完全定义所有内容,那么语言将更难以使用。
答案 2 :(得分:1)
您正在调用已声明的函数,并打印其返回值。
该功能尚未定义;但你只需要一个声明来调用它。该定义甚至可以在另一个源文件中,在编译后与此文件链接;它仍然可以工作,并返回其定义应该返回的任何内容。
答案 3 :(得分:1)
此代码只有一个缺陷。它必须包含标题<string>
否则其他编译器可能会发出错误。:)
所以程序应该包含指令
#include <string>
您正在打印已定义的内容。您正在打印在调用之前声明的函数HelloWorld
的返回值
string HelloWorld();
在其定义中,该函数具有return语句,该语句返回字符串文字“Hello World”
string HelloWorld(){
return "Hello World";
}
由于类std::string
具有接受字符串文字作为参数的构造函数,因此创建类型为std::string
的对象作为返回值并打印它。