Organization of C files

后端 未结 8 1668
悲哀的现实
悲哀的现实 2020-12-13 13:30

I\'m used to doing all my coding in one C file. However, I\'m working on a project large enough that it becomes impractical to do so. I\'ve been #including them together but

相关标签:
8条回答
  • 2020-12-13 14:11

    Try to make each .c focus on a particular area of functionality. Use the corresponding .h file to declare those functions.

    Each .h file should have a 'header' guard around it's content. For example:

    #ifndef ACCOUNTS_H
    #define ACCOUNTS_H
    ....
    #endif
    

    That way you can include "accounts.h" as many times as you want, and the first time it's seen in a particular compilation unit will be the only one that actually pulls in its content.

    0 讨论(0)
  • 2020-12-13 14:12

    Your question makes it clear that you haven't really done much serious development. The usual case is that your code will generally be far too large to fit into one file. A good rule is that you should split the functionality into logical units (.c files) and each file should contain no more than what you can easily hold in your head at one time.

    A given software product then generally includes the output from many different .c files. How this is normally done is that the compiler produces a number of object files (in unix systems ".o" files, VC generates .obj files). It is the purpose of the "linker" to compose these object files into the output (either a shared library or executable).

    Generally your implementation (.c) files contain actual executable code, while the header files (.h) have the declarations of the public functions in those implementation files. You can quite easily have more header files than there are implementation files, and sometimes header files can contain inline code as well.

    It is generally quite unusual for implementation files to include each other. A good practice is to ensure that each implementation file separates its concerns from the other files.

    I would recommend you download and look at the source for the linux kernel. It is quite massive for a C program, but well organised into separate areas of functionality.

    0 讨论(0)
  • 2020-12-13 14:16

    You should regard .h files as interface files of your .c file. Every .c file represents a module with a certain amount of functionality. If functions in a .c file are used by other modules (i.e. other .c files) put the function prototype in the .h interface file. By including the interface file in your original modules .c file and every other .c file you need the function in, you make this function available to other modules.

    If you only need a function in a certain .c file (not in any other module), declare its scope static. This means it can only be called from within the c file it is defined in.

    Same goes for variables that are used across multiple modules. They should go in the header file and there they have to marked with the keyword 'extern'. Note: For functions the keyword 'extern' is optional. Functions are always considered 'extern'.

    The inclusion guards in header files help to not include the same header file multiple times.

    For example:

    Module1.c:

        #include "Module1.h"
    
        static void MyLocalFunction(void);
        static unsigned int MyLocalVariable;    
        unsigned int MyExternVariable;
    
        void MyExternFunction(void)
        {
            MyLocalVariable = 1u;       
    
            /* Do something */
    
            MyLocalFunction();
        }
    
        static void MyLocalFunction(void)
        {
          /* Do something */
    
          MyExternVariable = 2u;
        }
    

    Module1.h:

        #ifndef __MODULE1.H
        #define __MODULE1.H
    
        extern unsigned int MyExternVariable;
    
        void MyExternFunction(void);      
    
        #endif
    

    Module2.c

        #include "Module.1.h"
    
        static void MyLocalFunction(void);
    
        static void MyLocalFunction(void)
        {
          MyExternVariable = 1u;
          MyExternFunction();
        }
    
    0 讨论(0)
  • 2020-12-13 14:18

    To answer your additional question:

    This question precipitated my inquiry. The tea.h file makes no reference to the tea.c file. Does the compiler "know" that every .h file has a corresponding .c file?

    The compiler is not primarily concerned with header files. Each invocation of the compiler compiles a source (.c) file into an object (.o) file. Behind the scenes (i.e. in the make file or project file) a command line equivalent to this is being generated:

    compiler --options tea.c
    

    The source file #includes all the header files for the resources it references, which is how the compiler finds header files.

    (I'm glossing over some details here. There is a lot to learn about building C projects.)

    0 讨论(0)
  • A couple of simple rules to start:

    1. Put those declarations that you want to make "public" into the header file for the C implementation file you are creating.
    2. Only #include header files in the C file that are needed to implement the C file.
    3. include header files in a header file only if required for the declarations within that header file.

    4. Use the include guard method described by Andrew OR use #pragma once if the compiler supports it (which does the same thing -- sometimes more efficiently)
    0 讨论(0)
  • 2020-12-13 14:20

    As well as the answers supplied above, one small advantage of splinting up your code into modules (separate files) is that if you have to have any global variables, you can limit their scope to a single module by the use of the key word 'static'. (You could also apply this to functions). Note that this use of 'static' is different from its use inside a function.

    0 讨论(0)
提交回复
热议问题