【问题标题】:Structure used in other source files其他源文件中使用的结构
【发布时间】:2017-11-10 12:05:03
【问题描述】:

我有 3 个文件

//--------------reg_des.h---------------
struct reg
          {
              unsigned int i : 4;
              unsigned int j : 4;
          };
extern struct reg; 



//--------------reg_des.c---------------

struct reg xyz_reg = {.i = 2,.j = 1};


//--------------main.c---------------
#include "reg_des.c"
void  display_onmodule(struct reg xyz_reg_1)

int main()
{
   display_onmodule(xyz_reg);
}

void  display_onmodule(struct reg xyz_reg_1)
{
     .....
 }

这里我在头文件中声明了一个结构体,并在另一个源文件中初始化了结构体类型的变量。 实际上我想知道声明一个可以被多个源文件使用的结构是正确的方法吗?

【问题讨论】:

  • extern struct reg; 没有任何意义。要define 一个结构,您只需要定义,就像您在标题中所做的那样,要declare 这种结构的一个实例,您需要声明,即包括标题。要访问结构体reg 的实例化xyz_reg,您必须在头文件中将其定义为extern struct reg xyz_reg;
  • 要在不同的单元(文件)中访问结构reg的实例化xyz_reg,您必须在头文件中将其定义为extern struct reg xyz_reg;,并在每个源中包含头文件。
  • @Frankie_C 除了,他不应该那样做,因为这是糟糕的程序设计。
  • @Lundin 什么是可怕的:在头文件中定义结构和extern 引用?我没有提到,说实话,我什至没有注意到,在其他 C 文件中包含 C 文件是一个好主意或坏主意。
  • @Frankie_C 是的,跨多个文件使用外部/全局变量是 100% 不好的做法。除了const 合格的少数例外。

标签: c struct header structure extern


【解决方案1】:

不,这不是设计程序的正确方法——这是使用全局变量的意大利面条式编程。几乎不存在有理由使用全局(非const)变量的情况。

此外,如果您发现需要包含 .c 文件,则意味着您的设计完全失控了。我们永远只包含 .h 文件。

修复程序的最简单方法是:

//--------------reg_des.h---------------
#ifndef REG_H // always use header guards!
#define REG_H    

struct reg  // note: this bit-field is completely non-portable
{
    unsigned int i : 4;
    unsigned int j : 4;
};

void reg_init (struct reg* r);

#endif // REG_H


//--------------reg_des.c---------------
#include "reg_des.h"    

void reg_init (struct reg* r)
{
  *r = (struct reg) {.i = 2,.j = 1};
}




//--------------main.c---------------
#include "reg_des.h"

void  display_onmodule(struct reg xyz_reg_1);

int main()
{
   struct reg xyz_reg;
   reg_init(&xyz_reg);

   display_onmodule(xyz_reg);

   // pass on xyz_reg to x different files here, etc
}

void  display_onmodule(struct reg xyz_reg_1)
{
     .....
}

还有更好的设计,带有私有封装,但以上是可以接受的。

【讨论】:

  • 不是 main() 函数中 struct reg xyz_reg 的范围吗?但我希望它是全球性的
  • @GauravKumar 为什么?从来没有理由这样做。即使您正在编写一些硬件寄存器映射,也不应该使用全局变量。你也不应该使用位域,因为它们完全不可靠。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-07-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多