在C中的头文件中声明外部结构

问题描述 投票:0回答:2

我发现了一段让我有点感兴趣的代码,有一个头文件仅声明了用 C 语言编写的嵌入式系统代码中使用的结构。

这是找到的代码示例:

#ifdef _structures_h_
 
extern struct{
    uint16_t  State_ON;
    uint16_t  State_OFF;
    uint16_t  State_HI;    
    uint16_t  Counter;
}Switch;

#endif


#ifndef _structures_h_
#define _structures_h_

struct{
    uint16_t  State_ON;
    uint16_t  State_OFF;
    uint16_t  State_HI;    
    uint16_t  Counter;
}Switch;

#endif

在使用这些结构的源文件中,在其中一些文件中,包含是这样完成的:

#define _structures_h_
#include "structures.h"

其他只是包含头文件,如下所示:

#include "structures.h"
  • 我的疑问是,是否有某种原因在同一个头文件中以两种方式声明结构?

  • 在头文件管理器中将相同的结构声明为 extern 或不在头文件管理器中声明相同的结构的编码是否有任何差异或相关影响?

这是我第一次发现这样的情况,并且我无法找到使用此功能的合理解释。

c struct
2个回答
0
投票

这个结构基本上可以归结为:

标题.h

#ifdef _structures_h_

extern struct {
  int  State_ON;
  int  State_OFF;
} Switch;

#endif

#ifndef _structures_h_
#define _structures_h_

struct {
  int  State_ON;
  int  State_OFF;
} Switch;

#endif

文件1.c

#include "header.h"

void Function();

int main(void)
{
    Switch.State_ON = 2;
    Function();
}

file2.c

#include <stdio.h>

#define _structures_h_
#include "header.h"

void Function()
{
    printf("Switch.State_ON = %d\n", Switch.State_ON);
}

这非常丑陋,因为:

  • 在 header.h 中,结构体被重复,这很容易出错
  • 尚不清楚何时以及为什么我们需要在包含 header.h 之前拥有
    #define _structures_h_
  • 整件事很令人困惑,因为你自己也经历过。

通常的做法如下所示:

标题.h

#ifndef _structures_h_
#define _structures_h_

typedef struct {
  int  State_ON;
  int  State_OFF;
} SwitchStruct;

extern SwitchStruct Switch;   // declare the Switch variable so that anybody
                              // who includes header.h can use it
#endif

文件1.c

#include "header.h"

SwitchStruct Switch;  // the one and only place where the variable
                      // Switch is defined
void Function();

int main(void)
{
    Switch.State_ON = 2;
    Function();
}

file2.c

#include <stdio.h>
#include "header.h"

void Function()
{
 // we can use Switch because it is declared in header.h
    printf("Switch.State_ON = %d\n", Switch.State_ON);
}

0
投票

两个代码段之间的区别在于,在第一个代码段(具有

extern
关键字的代码段)中,结构体变量是 declared 但不是 defined。也就是说,代码指定
Switch
变量是在其他地方定义的(可能在另一个翻译单元中,或者可能在同一 TU 中较早包含的标头中)。然而,在第二节中,Switch变量被正式声明
并定义
;另请注意,在第二个片段中,还定义了 _structures_h_ 标记,以便后续包含的标头将使用第一部分,以防止
Switch
变量的多个定义。
但我同意你和其他回答者的观点,这样的代码既令人困惑又容易出错:例如,在没有 

_structures_h_

的多个翻译单元中使用该标头可能会导致

Switch
变量的多个定义。另外,与其使用
#ifndef ...
块,一个简单的
#else
就足够了,并使事情变得更清晰(恕我直言)。
    

© www.soinside.com 2019 - 2024. All rights reserved.