C++ 为什么要在多个cpp文件中包含相同的头文件,然后再编译它们?

C++ 为什么要在多个cpp文件中包含相同的头文件,然后再编译它们?,c++,header-files,C++,Header Files,例如,我有两个cpp文件:f1.cpp和f2.cpp,还有一个头文件:xxx.h f1.cpp具有以下源代码: #include <iostream> #include "xxx.h" using namespace std; int main () { rect rplace; polar pplace; cout<<"Enter the x and y values: "; while (cin>>rplace.x>

例如,我有两个cpp文件:f1.cpp和f2.cpp,还有一个头文件:xxx.h

f1.cpp具有以下源代码:

#include <iostream>
#include "xxx.h"

using namespace std;

int main ()
{
    rect rplace;
    polar pplace;
    cout<<"Enter the x and y values: ";
    while (cin>>rplace.x>>rplace.y)
    {
        pplace=rect_to_polar(rplace);
        show_polar(pplace);
        cout<<"Next two numbers (q to quit): ";
    }
    cout<<"Done.\n";
    return 0;
}
#include <iostream>
#include <cmath>
#include "xxx.h"

polar rect_to_polar (rect xypos)
{
    using namespace std;
    polar answer;
    answer.distance=sqrt(xypos.x*xypos.x+xypos.y*xypos.y);
    answer.angle=atan2(xypos.y, xypos.x);
    return answer;
} 

void show_polar (polar dapos)
{
    using namespace std;
    const double Rad_to_deg=57.29577951;
    cout<<"distance="<<dapos.distance;
    cout<<", angle= "<<dapos.angle*Rad_to_deg;
    cout<<"degrees\n";
}

我认为应该有一个编译器错误,因为头
xxx.h
iostream
包含两次:一次在f1.cpp中,一次在f2.cpp中。但是所有的东西都是编译的,所以我不明白它是如何工作的。

预处理器只是读取头文件,然后将它们放入翻译单元,在那里执行
#include
指令。如果一个源文件中包含一个头文件,则只有该文件知道该头文件中的声明

您还应该知道声明和定义之间的区别。当你声明某个东西时,你只是告诉编译器“这个东西存在并且是这个和那个类型的”。当您定义某个东西时,您会告诉编译器“这就是我之前声明的东西”

同一事物可以有多个声明。因为它们只作为编译器的元数据,不在其翻译单元之外使用。但是,对某事物只能有一个定义。这就是为什么不能在多个源文件中包含的头文件中定义全局变量/函数


此外,在这个回答中,我将讨论“源文件”、“头文件”和“翻译单元”。头文件是您包含的文件。源文件是执行以下操作的文件(可以说)。翻译单元是完整的预处理源代码,包含源代码和所有包含的头文件,并传递给实际的编译器。

预处理器只需读取头文件并将其放入执行
#include
指令的翻译单元中。如果一个源文件中包含一个头文件,则只有该文件知道该头文件中的声明

您还应该知道声明和定义之间的区别。当你声明某个东西时,你只是告诉编译器“这个东西存在并且是这个和那个类型的”。当您定义某个东西时,您会告诉编译器“这就是我之前声明的东西”

同一事物可以有多个声明。因为它们只作为编译器的元数据,不在其翻译单元之外使用。但是,对某事物只能有一个定义。这就是为什么不能在多个源文件中包含的头文件中定义全局变量/函数


此外,在这个回答中,我将讨论“源文件”、“头文件”和“翻译单元”。头文件是您包含的文件。源文件是执行以下操作的文件(可以说)。翻译单元是完整的预处理源代码,包含源代码和所有包含的头文件,并传递给实际的编译器。

预处理器只需读取头文件并将其放入执行
#include
指令的翻译单元中。如果一个源文件中包含一个头文件,则只有该文件知道该头文件中的声明

您还应该知道声明和定义之间的区别。当你声明某个东西时,你只是告诉编译器“这个东西存在并且是这个和那个类型的”。当您定义某个东西时,您会告诉编译器“这就是我之前声明的东西”

同一事物可以有多个声明。因为它们只作为编译器的元数据,不在其翻译单元之外使用。但是,对某事物只能有一个定义。这就是为什么不能在多个源文件中包含的头文件中定义全局变量/函数


此外,在这个回答中,我将讨论“源文件”、“头文件”和“翻译单元”。头文件是您包含的文件。源文件是执行以下操作的文件(可以说)。翻译单元是完整的预处理源代码,包含源代码和所有包含的头文件,并传递给实际的编译器。

预处理器只需读取头文件并将其放入执行
#include
指令的翻译单元中。如果一个源文件中包含一个头文件,则只有该文件知道该头文件中的声明

您还应该知道声明和定义之间的区别。当你声明某个东西时,你只是告诉编译器“这个东西存在并且是这个和那个类型的”。当您定义某个东西时,您会告诉编译器“这就是我之前声明的东西”

同一事物可以有多个声明。因为它们只作为编译器的元数据,不在其翻译单元之外使用。但是,对某事物只能有一个定义。这就是为什么不能在多个源文件中包含的头文件中定义全局变量/函数


此外,在这个回答中,我将讨论“源文件”、“头文件”和“翻译单元”。头文件是您包含的文件。源文件是执行以下操作的文件(可以说)。翻译单元是完整的预处理源代码,包含源代码和所有包含的头文件,并传递给实际的编译器。

如果头文件只包含声明,并且我可以有多个相同的声明,那么为什么我不能在头文件中写两次极性结构声明?但是我可以双重函数声明。@Sunrise有些东西,比如函数,如果声明相同,可以在同一个翻译单元中多次声明。但是像结构和类这样的东西有点不同,因为实际上定义了结构,但是结构定义就像一个声明,它本身不会生成任何代码
struct polar
{
    double distance;
    double angle;
};

struct rect
{
    double x;
    double y;
};

polar rect_to_polar (rect xypos);
void show_polar(polar dapos);