C++ 理解C++;汇编

C++ 理解C++;汇编,c++,ide,header,compiler-errors,build-system,C++,Ide,Header,Compiler Errors,Build System,我最近意识到,一般来说,我不知道c/c++编译器是如何工作的。我承认这最初是因为我试图理解头球后卫,但后来我意识到我缺乏编译的工作原理 以Visual C++为例;有“头文件”文件夹、“资源文件”文件夹和“源文件”文件夹。分离这些文件夹和您在其中放置的内容有什么意义吗?对我来说,它们都是源文件。以代码片段为例: 片段1 及 及 及 //main.cpp #包括 #包括“a1.cpp” void main() { 库特 未编译头文件 #include指令直接粘贴可包含文件的内容,而不是#inclu

我最近意识到,一般来说,我不知道c/c++编译器是如何工作的。我承认这最初是因为我试图理解头球后卫,但后来我意识到我缺乏编译的工作原理

以Visual C++为例;有“头文件”文件夹、“资源文件”文件夹和“源文件”文件夹。分离这些文件夹和您在其中放置的内容有什么意义吗?对我来说,它们都是源文件。以代码片段为例:

片段1 及

//main.cpp
#包括
#包括“a1.cpp”
void main()
{
库特
  • 未编译头文件
  • #include指令直接粘贴可包含文件的内容,而不是#include行
  • 所有源文件(main的redargless)都编译成.o或.obj文件
  • 所有obj文件都与外部.lib文件(如果有)链接在一起
  • 你会得到一个可执行文件
  • 关于第2点:

    example
    //a.h
    int
    
    //b.h
    x = 
    
    //c.h
    5
    
    //main.cpp
    #include <iostream>
    int main()
    {
    #include "a.h"
    #include "b.h"
    #include "c.h"
    ;
    
    std::cout << x << std::endl; //prints 5 :) 
    }
    
    示例
    //a、 h
    int
    //b、 h
    x=
    //c、 h
    5.
    //main.cpp
    #包括
    int main()
    {
    #包括“a.h”
    #包括“b.h”
    #包括“c.h”
    ;
    
    std::cout您的问题实际上不是关于编译器,而是关于IDE如何处理整个构建系统。大多数C/C++项目的构建系统分别编译每个
    .C
    .cpp
    文件,然后将生成的对象文件链接到最终的可执行文件中。在您的情况下,IDE正在编译任何您在项目中拥有的文件扩展名为
    .cpp
    ,然后链接生成的对象。您看到的行为可以解释如下:

  • a1.cpp
    缺少一个
    ,因此当IDE尝试编译该文件时,您会收到关于“文件意外结束”的错误

  • b
    未在
    main.cpp
    编译单元中的任何位置声明,因此您会收到一个关于未定义标识符的错误

  • b
    存在于
    main.cpp
    a1.cpp
    编译单元中(显然是在
    a1.cpp
    中,并通过
    包含在
    main.cpp
    中)。您的IDE编译这两个文件-现在
    a1.o
    main.o
    每个文件都包含一个名为
    b
    的对象。链接时,会出现重复符号错误

  • 这里需要注意的一点是,IDE编译每个
    .cpp
    文件,而不仅仅是
    main.cpp
    及其包含的文件,然后链接生成的对象,这一点解释了您看到的所有行为


    我建议用一个创建自己的MaFC++文件来设置命令行测试项目,它将教你所有的构建系统的内部工作,然后你可以将这些知识应用到IDE的内部工作。

    < P>编译器从你告诉它的地方提取源文件。编译器需要做什么,不同的文件夹就在那里,因为IDE就是这样组织文件的

    此外,代码段2中的错误来自链接器,而不是编译器。 编译器已将main.cpp和a1.cpp编译成目标文件main.obj和a1.obj,然后链接器正试图生成一个组合这些目标文件的可执行文件,但变量b同时位于a1.obj(直接)和main.obj(通过包含a1.cpp)中,因此您得到了“已定义”的错误。

    include语句将该文件插入到生成#include的文件中。因此,您的代码片段3 main.cpp在编译之前将变成以下内容

        // main.cpp    
        // All sorts of stuff from iostream
        //a1.cpp
        int b = 4;
        void main()
        {
            cout << b;
        }
    
    //main.cpp
    //来自iostream的各种东西
    //a1.cpp
    int b=4;
    void main()
    {
    
    您在案例1和案例3中看到的问题是VS特有的。VS显然试图编译main.cpp和a1.cpp

    案例1:当VS试图编译a1.cpp时,它有一个语法错误(缺少分号),编译失败

    案例2:您没有在main.cpp或任何包含的文件中声明变量
    b
    。因此编译失败


    案例3:这是一个链接器错误。由于include,在main.cpp和a1.cpp中都声明了
    int b
    。因为它们都不是静态的或外部的,所以在同一范围内声明了两个具有相同标识符的全局变量。这是不允许的。

    您告诉构建系统要编译哪些文件。对于ViSUAL C++,它将自动编译任何添加到项目中的名为*.CPP的文件。虽然你可以进入项目设置并告诉它不要。

    它不会编译名为*.h的文件(但如果您明确告诉它,它可以编译)

    #include指令是编译器在进行任何编译之前处理的东西(称为预处理器)。它基本上会获取指向的文件,并在#include指令出现在文件中时将其粘贴到正在编译的源文件中。然后编译器将整个内容编译为一个完整的单元

    因此,在您的示例中:

    片段1

    构建系统分别编译a1.cpp和main.cpp。因此,当它遇到错误om a1.cpp时,它会报告它

    片段2

    请注意,它单独编译这些文件,彼此不了解,因此当您在main.cpp中引用b时,它不知道a1.cpp中定义了b

    片段3

    现在你已经在main.cpp中包含了a1.cpp,所以它编译main.cpp,看到b的定义并说,好的,我在全局范围内有一个b。然后它编译a1.cpp,并说,好的,我在全局范围内有一个b


    <>现在链接器在AN和A=中尝试把A1和Advin结合在一起,现在告诉你,嘿,我有2个B的ATE全局范围。没有好的。

    < P>因为似乎有两种方式理解你的问题,我将回答C++的理解。
    //main.cpp
    #include <iostream>
    #include "a1.h"
    void main()
    {
       cout << r;
    }
    
    //a1.h
    int r=4 //<--semicolon left out on purpose
    
    //a1.cpp
    int b = 4;  
    
    //main.cpp
    #include <iostream>
    void main()
    {
       cout << b;
    }
    
    //a1.h
    int r=4 //<--semicolon left out on purpose
    
    //a1.cpp
    int b = 4;  
    
    //main.cpp
    #include <iostream>
    #include "a1.cpp"
    void main()
    {
       cout << b;
    }
    
    example
    //a.h
    int
    
    //b.h
    x = 
    
    //c.h
    5
    
    //main.cpp
    #include <iostream>
    int main()
    {
    #include "a.h"
    #include "b.h"
    #include "c.h"
    ;
    
    std::cout << x << std::endl; //prints 5 :) 
    }
    
        // main.cpp    
        // All sorts of stuff from iostream
        //a1.cpp
        int b = 4;
        void main()
        {
            cout << b;
        }