【问题标题】:Functions declared and defined in a .c file在 .c 文件中声明和定义的函数
【发布时间】:2018-11-09 04:40:58
【问题描述】:

当我浏览大量源代码时,我遇到了一些文件,其中只声明了一个函数,比如“code.h”,但在“code.c”中声明和定义了许多函数。

在 .c 文件中声明和定义函数的确切用途是什么? 我们如何从其他源文件访问源文件中的这些函数之一?

如果有人能提供一个例子,那将会很有帮助。谢谢

【问题讨论】:

    标签: c header-files paradigms


    【解决方案1】:

    将复杂的例程拆分为多个较小的例程可能会使代码更易于理解,并且还允许您遵循单一职责原则 (What is an example of the Single Responsibility Principle?)。通过仅在 .c 文件中声明和定义它们(并将它们声明为 static),您可以对用户隐藏内部详细信息。

    例如,如果您创建一个库,那么您的标题只能显示您希望用户使用的公共功能。

    因此,如果您希望包含标头的任何人都可以使用这些功能,请仅将您的功能放在标头中。

    如果您想在 .c 文件中保留一个内部函数,请认真考虑添加 static 关键字:what is the advantage of static function?

    ---编辑---

    我们如何从其他源文件访问源文件中的这些函数之一?

    如果函数不是static,从技术上讲,你可以在任何你想要的地方声明它并在那里使用它。但是,根据上述论点,这将是不好的做法。

    例子:

    交流

    int secret_a(int x)
    {
        return x+1;
    }
    

    main.c

    #include <stdio.h>
    
    //access a secret function from a.c
    int secret_a(int);
    
    int main()
    {
        printf("secret_a(3) gives: %d\n", secret_a(3));
        return 0;
    }
    
    • (*) C 语言允许的任何地方

    【讨论】:

      【解决方案2】:

      我们如何从其他源文件访问源文件中的这些函数之一?

      这就是在头文件中定义一些函数的全部想法,而一些只在 c 文件中。

      头文件中定义的函数,可以被其他源文件调用。 仅在源文件中定义的函数可以隐藏 - 通常将仅在源文件中声明的函数标记为静态。 这使得它们的可见性仅限于文件范围(只有同一文件中的代码才能“看到”函数)。

      【讨论】:

        【解决方案3】:

        这样做的原因是为了将代码拆分为更清晰和排序的格式,以便可以将与特定操作相关的函数组合到一个文件中,然后从另一个文件中调用。注意:这不是强制性的,而是一种良好的编程习惯。

        现在有两种方法可以做到: 1.包括文件 2.将函数声明为extern,然后在链接时链接。

        1。 包含文件是您可能在手头代码中看到的方法。函数定义在一个文件中,该文件使用 #include"filename.[h/c]" 包含在内,然后调用给定文件中声明的函数。

        file_to_include.c

        void my_func()
        {
        printf("Hello!\n");
        }
        

        file_that_include.c

        #include<stdio.h>
        #include"file_to_include.c"
        int main()
        {
         my_func();
         return 0;
         }
        

        编译你就行了

        gcc file_that_include.c
        
        1. 使用 extern 可以做同样的事情,但不使用 #include 指令

        file_to_include.c

        void my_func()
        {
        printf("Hello!\n");
        }
        

        file_that_include.c

        #include<stdio.h>
        
        extern void my_func();
        int main()
        {
         my_func();
         return 0;
         }
        

        在这种情况下,您需要在编译时将这两个文件都提供给编译器

        gcc file_that_include.c file_to_include.c
        

        【讨论】:

          【解决方案4】:

          我建议阅读“extern”关键字。

          根据我对您问题的理解,您有两个文件 - “code.h”和“code.c”。但是,“code.h”只在“code.c”中声明了某些函数:

          代码.h

          int func1();
          int func2();
          

          code.c

          int func1()
          {
            return 1;
          }
          
          int func2()
          { 
            return 2;
          }
          
          int func3()
          { 
            return 3;
          }
          

          main.c

          #include "stdio.h"
          #include "code.h"
          
          extern int func3();
          
          int main()
          {
            printf("%d ", func1());
            printf("%d ", func2());
            printf("%d ", func3());
          }
          

          使用 gcc 编译:

          gcc main.c code.c

          产量:

          main.c: In function ‘main’:
          main.c:10:17: warning: implicit declaration of function ‘func3’ [-Wimplicit-function-declaration]
             printf("%d ", func3());
          

          当执行时:

          1 2 3
          

          “extern”关键字基本上告诉编译器“有一个具有此声明的函数的定义”进行编译。在链接过程中,链接器会找到定义并链接到它。

          然而这是一种笨拙的方式,因为调用者(“main.c”)需要知道“code.c”中发生了什么,并不断添加更多的外部声明等。

          因此,宁愿在“code.h”中包含具有全局范围的函数。如果“code.c”中有没有全局作用域的函数,请考虑将它们设为“静态”。

          更多阅读: Effects of the extern keyword on C functions

          【讨论】:

            最近更新 更多