【问题标题】:Should I define functions in .h file or just declare them?我应该在 .h 文件中定义函数还是只声明它们?
【发布时间】:2020-09-28 05:11:57
【问题描述】:

我是 C 新手,遇到了这样的说法:

“函数需要在 .h 文件中声明,并且除了内联函数之外没有定义”。

那么我的问题是,标准函数在哪里定义?

【问题讨论】:

  • 您误解了该声明。就是说头文件通常应该只包含函数声明而不是函数定义。函数定义在.c 文件中。这对于标准函数和您自己的函数都是一样的。
  • @kaylum 更详细地说,当我们包含 stdio.h 时,头文件中只包含函数和全局变量的声明,对吗?这就是我的困惑开始的地方。链接器从哪里知道它们的声明。 (整个论点以标准标题开始)
  • 链接器在标准位置以及您在命令行上告诉它的任何位置查找库(例如,gcc-L 选项)。这些库具有包含已编译函数定义代码的二进制对象。 (粗略地说)
  • @kaylum 好的。所以,当我制作自己的头文件时,我只需要声明该文件中的函数并制作一个包含所有声明的文件并编译它。然后告诉编译器它需要从哪里链接它的目标代码。对吗?

标签: c function header-files function-prototypes function-definition


【解决方案1】:

是的,函数是在 .h 文件中声明的,它们是在 .c 文件中定义的

【讨论】:

    【解决方案2】:

    "函数需要在.h 文件中声明,并且除了内联函数之外没有定义"

    来源不明

    很遗憾,这句话含糊不清,也不完全正确。

    1. 函数不需要需要.h 文件中声明。您可以.c 文件中声明一个函数,甚至完全省略声明(取决于您的编码风格和函数定义的位置)。

      注意后者,编译器从上到下读取文件。

      例如,这是源文件foo.c的内容:

      void foo (void)
      {
         // absolute foo / translated: It really does not make anything useful.
         // this function is only to illustrate the omission of the prototype.
      }
      
      int main (void)
      {
         foo();
      }
      

      要调用foo(),我们根本不需要声明foo(),因为定义在源代码中使用之前(编译器从上到下读取)。

      它会落后吗,我们需要一个声明来告诉编译器foo() 是什么,f.e.:

      void foo (void);    // foo() needs to be declared. Else the compiler does not know 
                          // what foo is when foo is called in main.
      
      int main (void)
      {
         foo();
      }
      
      void foo (void)
      {
         // absolute foo.
      }
      

      将函数的声明/原型放在单独的标头中只是一种常见的用法,但实际上您不需要这样做。这是标题版本:

      foo.c:

      #include "foo.h"      // We need to include the header to gain the prototype.
                            // Note that `foo.h` needs to be in the same directory 
                            // as `foo.c` in this case. Else you need to specify the 
                            // full path to foo.h .
      
      int main (void)
      {
         foo();
      }
      
      void foo (void)
      {
         // absolute foo.
      }
      

      foo.h:

      void foo (void);
      

    这句话的真正含义是:

    1. 绝对不应该在.h 文件中定义函数(因为这些是头文件,而不是源文件),唯一的例外是inline 函数,它确实可以在.h 文件中定义。李>

    "那么我的问题是,标准函数在哪里定义?"

    这是一个完全不同的问题和特定于实现的问题。这些函数以完全或半编译的形式存储。如果不关注任何特定的实现(操作系统、编译器),我无法在这里回答。

    【讨论】:

      【解决方案3】:

      “函数需要在 .h 文件中声明,并且除了内联函数之外没有定义”。

      您在标头中声明了一个函数的存在。供所有家属查看。
      您在源文件中实现(定义)函数。家属看不到这一点。
      头文件是 API 或您的 C 文件,可在应用程序的其他地方使用,隐藏实现。
      内联函数的例外与以下事实有关,即在编译依赖项时,编译器必须知道放置而不是函数调用的内容。

      仅在源文件中(私有)使用的函数不需要在头文件中声明。为什么要告诉其他代码呢?

      我的问题是标准函数在哪里定义?

      在编译库中。你只知道它们存在,而不知道它们存在的地方。实现对您隐藏。 linker 连接点。

      【讨论】:

      • 我现在有一个奇怪的问题。根据包含的头文件(标准头文件),链接器是否链接所有 .a 或 .so 文件,或者它知道要链接哪个文件。
      • @rajiv 无。链接器提供了对象(.a 和 .o),它们将它们链接到您的可执行文件。预处理器 (.h) -> 编译器 (.c) -> 链接器 (.o) -> 应用程序
      猜你喜欢
      • 2020-03-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多