这里基本上没有技术考虑。也就是说,这个决定本质上与软件或硬件的运行方式无关。
此决定中的考虑因素是人为因素。当我们就如何组织源代码做出决定并制定惯例时,我们这样做是为了实现以下目标: 使代码更易于编写。使代码更易于维护。减少错误。
这些都是人为的考虑。人类的行为方式与完美机器不同:他们会犯错误。他们忘记了事情。它们可以更好地处理分成可管理大小的问题。
通常,头文件用于声明在多个源文件中使用的东西(例如许多不同的人在许多不同程序中使用的库例程)并将声明与定义分开,以便您可以编译一个使用例程而不必在源文件中包含这些例程的定义的源文件。从技术上讲,您可以将声明复制到每个源文件中,并且您会从编译器中得到相同的结果。但这违反了几个目标:它使代码更难编写,因为每当例程定义发生更改时,都必须更改声明的所有副本。而且它会增加错误:有时,人们会忘记或错过需要更改的副本。
因此,您可以将结构对象的定义放入 .c 文件中。您也可以将其放入头文件中。这会帮助您实现目标吗?
请注意,结构对象被声明为静态的。如果它在多个源文件中编译,则生成的每个目标文件都将有一个单独的副本。当您将目标文件链接到单个可执行文件中时,它将具有相同数据的多个副本(除非您使用的开发人员工具非常非常好)。这是一种浪费,所以这不是一个好主意。但是,如果您只在一个源文件中编译它,那么只有人为因素才重要:您是否有可能犯错误并同时编译 file1.c 和 file2.c?当其他人处理这段代码时,他们会理解 mystruct 是如何以及为什么定义的吗?以此类推。
我曾参与过适合在单独的源文件中定义对象的项目。例如,有时需要准备一个计算数据表并将其包含在程序的源中。在这种情况下,将该表保存在单独的源文件中是合理的。
通常,在这种情况下使用的解决方案是使用仅包含表定义而不包含其他任何内容的源文件。在那个源文件中,表将被声明为外部的,使用“extern”关键字。在头文件中,表将被声明但未定义。每个使用该表的源文件都将包含用于声明该表的头文件。定义表的源文件还包括头文件。 (这样做时,如果头文件和源文件不匹配,编译器会报错。这样可以避免头文件出错。)
定义表的源文件将被编译成一个目标模块。包含程序其他内容的源文件将被编译成单独的目标模块。然后使用链接器将所有目标模块组合成一个程序。
在您的情况下,是否有任何理由将对象声明为静态?如果有,那么将其定义包含在另一个源文件中的这种解决方案可能是合适的。但是,很少有这样的原因。如果您认为将定义放在单独的文件中有助于您组织源代码,那么更合适的解决方案是如上所述将对象声明为外部对象,并单独编译源代码。
使用 GCC 时,您可以像这样将源代码编译为对象模块:
gcc -c -o name0.o name0.c
gcc -c -o name1.o name1.c
“-c”开关表示“只需编译到对象并停止,而不是执行下一步链接以生成可执行文件。”“-o”开关指定输出文件的名称。
然后,您可以像这样将对象模块链接到可执行文件:
gcc -o 程序名0.o name1.o