-4

我正在使用 C++ MinGW 编译器,并且试图弄清楚如何使用方法和创建方法。这是我尝试过的:

#include <iostream>
using namespace std;

int main()
{
        test();
}

void test()
{
        cout << "Hello" << endl;
}

我是 C++ 的初学者,但我对 Java 了解很多。这是编译器消息:

12:09:06 **** Incremental Build of configuration Debug for project String Gen ****
Info: Internal Builder is used for build
g++ -O0 -g3 -Wall -c -fmessage-length=0 -o main.o "..\\main.cpp" 
..\main.cpp: In function 'int main()':
..\main.cpp:6:14: error: 'test' was not declared in this scope

12:09:06 Build Finished (took 411ms)
4

2 回答 2

4

test()必须在之前声明main()

#include <iostream>
using namespace std;

void test()
{
        cout << "Hello" << endl;
}

int main()
{
        test();
}

或者您可以使用前向声明:

#include <iostream>
using namespace std;

void test();

int main()
{
        test();
}

void test()
{
        cout << "Hello" << endl;
}

在 Java 和 C# 等语言中,声明的顺序并不重要,但对于 C 和 C++ 编译器,顺序确实很重要。基本上,在您的示例中,编译器会test();说“我不知道是什么test”。所以要么你在之前定义整个test()函数main(),要么你只是提前声明它告诉编译器“嘿,在我的程序的某个地方test有一个用这个签名命名的函数。”


一个更复杂的例子:

测试.h

void test();

测试.cpp

void test() {
    // Whatever...
}

主文件

#include "test.h"

int main() {
    test();
    return 0;
}
于 2013-07-10T03:52:45.367 回答
1

C++ 构建模型与 Java 模型完全不同。在 C++ 中,有各种实体的“声明”和“定义”,例如函数、类、方法等。C++ 源代码由一系列声明和定义组成。单个模块或“翻译单元”被编译成包含在该翻译单元中定义的任何实体的目标代码。然后,组成程序的编译翻译单元被“链接”在一起,其中一个翻译单元中定义的实体与它们在其他翻译单元中的用法相关联。

在翻译单元中,实体的某些使用只需要声明,而其他使用则需要完整的定义。例如,调用一个函数只需要声明该函数。创建一个指向对象的变量只需要声明对象的类型。创建一个类型是类类型(而不是指针)的变量需要类的完整定义。什么需要完整定义,什么只需要声明,取决于实现使用所需的内容。特别是如果使用只需要知道接口细节,那么声明就足够了,但是如果需要实现细节,那么就需要定义。

此外,指定 C++ 使得编译器几乎可以是单程的;声明和定义在使用之前必须出现在源代码中(大部分情况下;有一些例外),以便 C++ 在提及它时已经知道正在使用什么实体。


所以你的代码的问题是当编译器得到test()它时不知道它是什么test。它可以是类型、函数或变量。它不知道,因为它还没有被告知。你需要通过test事先声明来告诉它。

void test();

int main() {
  test();
}

现在编译器会在它尝试调用它时知道 test 是一个函数。而且由于调用函数不需要知道函数签名之外的任何内容,因此test如果您愿意,可以将定义放入一个完全不同的翻译单元中。您将编译两个翻译单元,然后链接器会将调用该函数的代码连接test()到另一个编译的翻译单元中的该函数的定义。


头文件是 C 和 C++ 中的一个常见技巧,它使在翻译单元之间共享声明的单一来源变得容易。它们不是绝对必要的,但是如果您通过在不同文件中声明稍有不同的内容来搞乱声明,那么您的程序可能会以意想不到和不可预测的方式失败。

#include指令只需获取您命名的任何文件并将内容粘贴到您的源代码中。这样一来,无论您在标头中放置什么,例如函数声明,您都有一个单一的来源。这样,您可以确保在您需要的每个文件中都包含相同的声明,而不必担心您在一个文件中的声明是否与另一个文件略有不同。

您还可以将类定义放在头文件中,因为需要在以特定方式使用该类的每个翻译单元中重复类定义。同样,您可以在每个翻译单元中手动写出所需的信息,但将定义粘贴在标题中并让#include指令为您完成复制和粘贴会更容易。


如果你想学习 C++,我建议你买一本好书。如果您还不熟悉编程,我会推荐Programming: Principles and Practice Using C++。既然你说你已经编程了,那么我听说对你来说更好的书可能是Accelerated C++

于 2013-07-10T04:37:08.467 回答