我是刚开始使用头文件,但不确定自己在做什么错。我的代码可以编译,没有任何错误,但是永远不会要求用户输入整数,也永远不会显示其乘积。我正在使用Visual Studio社区。有任何想法吗?谢谢!
将头文件另存为.h而不是.cpp也是标准约定吗?
我的源文件中有:
#include <iostream>
#include "headerp1.cpp"
int product();
int main() {
int product();
return 0;}
在我的头文件(标题为headerp1.cpp)中,我有:
#include <iostream>
int product() {
int num1, num2, product;
std::cout << "Please enter two integers: \n";
std::cin >> num1 >> num2;
product = num1 * num2;
std::cout << "The product is " << product << "\n";
return 0;}
答案 0 :(得分:3)
头文件通常应包含功能声明,而不应包含功能 definitions 。我推荐这样的结构:
headerp1.h:
#ifndef HEADERP1_H
#define HEADERP1_H
/* Function declaration */
int product();
#endif // HEADERP1_H
headerp1.cpp:
#include "headerp1.h" /* Not strictly required in this case, but generally a good idea */
#include <iostream>
/* Function definition */
int product() {
int num1, num2, product;
std::cout << "Please enter two integers: \n";
std::cin >> num1 >> num2;
product = num1 * num2;
std::cout << "The product is " << product << "\n";
return 0;
}
main.cpp:
#include "headerp1.h"
int main() {
/* Function invocation */
product();
return 0;
}
答案 1 :(得分:1)
在头文件中,您可以进行函数声明,并在源文件中实现它。看看this。
您的代码应如下所示:
源文件:src.cpp
#include "header.h"
int main()
{
product();
return 0;
}
int product()
{
int num1, num2, product;
std::cout << "Please enter two integers: \n";
std::cin >> num1 >> num2;
product = num1 * num2;
std::cout << "The product is " << product << "\n";
return 0;
}
头文件:header.h
#include <iostream>
int product();
答案 2 :(得分:1)
在开始使用内联函数之前,模板在头文件中没有任何可做任何事情的代码。另外,按照惯例,头文件的名称以.h
或.hpp
结尾,而不是.cpp
。但这只是一个约定,您实际上可以给它们起任何喜欢的名字。但是,如果您不遵守约定,则会使所有人感到困惑。
在您的情况下,头文件是完全不需要的,而且会分散注意力。我想您只是这样做,因为您的作业需要这样做。
C和C ++具有称为“编译单元”的概念。这表示编译器在给定调用中进行操作的全文。编译单元由源文件的文本以及每个包含#include
指令的文件组成。 #include
指令非常简单和愚蠢。它只是使该行代码(#include
指令本身)被替换为包含文件的内容。
在您的情况下,您没有做任何有经验的C或C ++程序员会做的事情,因为整个程序中总共只有一个编译单元。您的文件之一包括另一个。拥有一个编译单元是完全可以接受的。但是只有一个编译单元和两个文件不是,而且很奇怪。
通常,您需要至少拥有两个文件才能使第三个“标头”文件有意义。当您有两个文件需要共享它们的某些部分时,将使用头文件。
在您的情况下:
file1.cpp
:
#include <iostream>
int product() {
int num1, num2, product;
std::cout << "Please enter two integers: \n";
std::cin >> num1 >> num2;
product = num1 * num2;
std::cout << "The product is " << product << "\n";
return 0;
}
和 file2.cpp
:
int product();
int main() {
int product();
return 0;}
我从您的包含main
的文件中删除了包含,因为它不需要任何一个。现在,您有两个文件,它们实际上是两个单独的编译单元。而且,实际上,在这种情况下,除了将main内部的product
函数的重新声明更改为对其的调用(只需删除int
)之外,不需要其他工作。如果编译这两个文件并将它们链接到一个程序中,它将起作用。无需#include
。
但是这里仍然有问题。对于这个小程序来说,这不是什么大问题,但是对于一个更大的程序,它将成为一个大问题。尤其是如果有几个不同的人正在处理它。
为了使这个问题更清楚,让我们重新组织一下程序:
product.cpp
(让其重命名以使情况更加清晰):
#include <iostream>
int product() {
int num1, num2, product;
std::cout << "Please enter two integers: \n";
std::cin >> num1 >> num2;
product = num1 * num2;
return product;
}
和 main.cpp
(我们也将其重命名):
#include <iostream> // Since this file now uses cout it needs this header.
int product();
int main() {
std::cout << "The product is " << product() << "\n";
return 0;
}
现在,如果您编译并链接该程序,它仍然可以正常工作。但是,如果将product.cpp
更改为以下内容,将会发生什么:
#include <iostream>
float product() {
int num1, num2;
float product;
std::cout << "Please enter two integers: \n";
std::cin >> num1 >> num2;
product = num1 / 3.0;
product = product * num2;
return product * 3;
}
程序仍将编译,但是您将得到无意义的输出。
解决方案是将共享声明移动到头文件。在这种情况下,共享声明是product
函数的声明。因此,让我们这样做:
product.hpp
:
int product();
product.cpp
:
#include <iostream>
#include "product.hpp"
float product() {
int num1, num2;
float product;
std::cout << "Please enter two integers: \n";
std::cin >> num1 >> num2;
product = num1 / 3.0;
product = product * num2;
return product * 3;
}
main.cpp
:
#include <iostream> // Since this file now uses cout it needs this header.
#include "product.hpp"
int main() {
std::cout << "The product is " << product() << "\n";
return 0;
}
请注意如何将产品声明(声明基本上就是它的意思,这是一行代码,说明“此物已存在”)如何从main.cpp
移到product.hpp
标头中文件。然后,我们在main.cpp
和product.cpp
中都包含该头文件,因此它们都看到关于int product()
存在的相同声明。
不幸的是,它将不再编译。编译器将看到int product()
的声明和float product()
的定义(并且同时声明,某些代码行可以是两行),并看到同一名称被声明为两个不同的名称。东西。
但这很好。编译器告诉我们出了点问题,因此我们可以对其进行修复。在这种情况下,请改为将product.hpp
改为float product();
,以便两个声明都一致。
现在它将编译,您将再次获得明智的答案。
这是头文件的目的。头文件包含一堆东西声明,以便每个人都可以同意这些声明是什么。通常,您至少有两个都需要查看特定声明的源文件,然后将该声明放入它们都包含的头文件中。通常,头文件是为定义其声明内容的源文件命名的。
我希望这个详尽而细致的解释会有所帮助。 :-)