C++ C标题定义订单/位置

C++ C标题定义订单/位置,c++,c,header,C++,C,Header,目前我正在尝试在C头文件中包含一个库。 以下是原始代码的外观: #ifndef SIMULATE_H #define SIMULATE_H #ifdef __cplusplus extern "C" { #endif #define RAM_SIZE 16320 #define STRING_SIZE 10 #define BUFFER_SIZE 100 long final_hex[RAM_SIZE]; char zero[STRING_SIZE]; char stringValue[ST

目前我正在尝试在C头文件中包含一个库。 以下是原始代码的外观:

#ifndef SIMULATE_H
#define SIMULATE_H

#ifdef __cplusplus
extern "C" {
#endif

#define RAM_SIZE 16320
#define STRING_SIZE 10
#define BUFFER_SIZE 100
long final_hex[RAM_SIZE];
char zero[STRING_SIZE];
char stringValue[STRING_SIZE];
char buffer[BUFFER_SIZE];
char checksum[BUFFER_SIZE];

#ifdef __cplusplus
}
#endif

#endif /* SIMULATE_H */
我想包括的是“
#包括”
”。这应该很容易,但我有一些疑问:

  • 这段代码是否意味着它可以是C和C++的头文件:

    #ifdef __cplusplus
    extern "C" {
    #endif
    
  • 当我在这里包含库时,我应该放在“
    外部”C“
    ”之前还是之后?这里的顺序对他们重要吗


  • 首先,你的意思可能是“包括而不是定义”

    如果你检查math.h你会发现它有自己的

    #ifdef __cplusplus
    extern "C" {
    #endif
    //...
    #ifdef __cplusplus
    }
    #endif
    
    部分。最好不要在外部“C”部分中包含外部标题

    这是一个很好的基础,但关于你的例子:

    • 如果您在extern“C”部分之前或之后包含,那么当前没有区别,因为您在标题中没有使用任何内容
    • 如果您使用外部标题的内容,则应在使用前将其包含在顶部,否则将出现错误
    • 如果您不打算使用math.h以外的任何定义或类型,嵌套include是不必要的,并且会创建无用的依赖关系,这在项目很小的时候并不重要,但会增加大型项目的构建时间-您应该在源文件的顶部单独包含这些文件

    我将重点介绍此代码的另一个方面:

    long final_hex[RAM_SIZE];
    

    全局数据结构需要在头文件中定义为
    extern
    。否则,包含标题的每个源文件都将尝试定义其自身的结构副本,这将在链接时导致错误(可能类似于“符号的多个定义”
    final_hex
    ”)。

    我没有资格添加注释,但我很好奇您是否想添加注释

    #include <math.h>
    
    #包括
    
    而不是

    #define <math.h>
    
    #定义
    
    我想你的意思是包括在内

    当您需要使用该库中定义的函数或结构时,可以包括其他库,如math.h

    当涉及到#include语句时,预处理器将用math.h文件的内容替换#include行

    仅当文件中的某些内容引用头文件中的某些内容时,才应包含头文件。就我所见,您发布代码的头文件没有引用math.h中的任何内容,因此您不应该将其包含在该文件中

    相反,您应该让源文件(*.c)使用simulate.h文件中的声明,并假定math.h包含这两个文件

    #include "simulate.h"
    #include <math.h>
    
    int main(void) {
        double root = sqrt(25.0); /* from math.h */
        int n = STRING_SIZE;      /* from simulate.h */
    }
    
    #包括“simulate.h”
    #包括
    内部主(空){
    double root=sqrt(25.0);/*来自math.h*/
    int n=字符串大小;/*来自simulate.h*/
    }
    
    就您的第一个问题而言,#ifdef#cplusplus只是预处理器的一个条件编译指令。如果变量(yc++)被定义(使用C++编译器),则它将在代码中添加代码:否则就不会


    如果您确实在simulate.h文件中包含math.h文件,那么就我所知,它的位置应该无关紧要,假设您以后在simulate.h中没有在
    #include

    之前引用math.h中的某些内容,谢谢您指出这一点!将它们定义为外部变量。对不起,我的意思是“#包含”。谢谢你的链接和解释!在本例中,我将尝试将include放在extern“c”部分之前。对于您提到的第三部分“如果您不打算使用math.h中的任何定义或类型”,您的意思是调用函数还是使用math.h中的变量?如果是,我是从math.h调用一个函数,但它在“simulate.c”文件中。很抱歉,问题中没有明确说明。我似乎应该在源文件“simulate.c”中包含该库,而不是“simulate.h”。谢谢你帮助我@Toby Zhou,是的,除非您在头文件中使用数据结构或math.h中的定义,否则您应该将其包含在源文件中,在本例中是simulate.c。没有明显的理由需要在头文件中包含
    simulate.h
    头中的任何声明本身都不需要
    头,因此包含它的唯一原因是,包含
    simulate.h
    的每个文件都不可避免地使用
    中的至少一个声明或定义。换言之,这只是一个小小的方便。通常情况下,您会保持最小的头文件以及自包含的头文件,以控制编译时间。它可能仍然是明智的,但它并不明显,这是明智的。是的,代码意味着报头打算从C和C++使用。但这很奇怪;没有函数,因此不清楚
    extern“C”
    是否有用-全局变量没有被类型安全链接破坏。请澄清您的“附加组件”。如果
    simulate.c
    中的代码正在调用
    中声明的函数,则c源代码应包含
    ,而不是标头。您应该只包含使外部头(此处,
    simulate.h
    )可供其他源文件使用所需的其他头。只有
    simulate.c
    才需要的任何内容都只能由
    simulate.c
    直接包含。如果您有一个函数
    extern void dump_simulation(文件*fp,常量字符*tag,常量模拟状态*sim_state)
    simulate.c
    中,然后您需要包含
    以获取
    文件的声明
    @JonathanLeffler抱歉,我没有说清楚,我想包含的原因是我在文件“simulate.c”中使用了一个函数,其中包括“simulate.h”。因此,在这种情况下,我是否应该将其包含在“simulate.c”中,而不是您提到的“self-contained”中的“simulate.h”?否则,您不需要在中使用