Differences between. C and. H files (reprinted)

Source: Internet
Author: User

A simple question: differences between. C and. H files
After learning C language for a few months, I feel more and more ignorant. It is also a subroutine, which can be defined in the. c file or in the. h file. What is the difference between the two files in usage?



Second floor:
Do not define subprograms in. h.
The function definition should be placed in. C, while. h only declares the function. Otherwise, repeated Function Definition errors will occur when multiple references are made.


Third floor:
. H is only used for declaration, and no code is generated after compilation.

4 floor:
The purpose is to implement software modularization.
Make the software structure clear, and make it easy for others to use the program you write

From the perspective of pure C syntax, you can certainly put anything in. H, because # include is equivalent to Ctrl-C Ctrl-V to. C.

In. h, there should be some macro definitions, variables, and function declarations to tell others what your program "can do and how to use it"
In. C, it defines all variables and functions and tells the computer how to implement your program"

Fifth floor:
Of course, if a. h is contained by multiple. c
In addition, if. H has an object (variable or function) definition, a duplicate definition error will occur.
The declaration can be infinite multiple times and can be defined only once

6th floor:
Generally, a C file is a module.
If your program only has one module (only one C file), you do not need to create an hfile.

Otherwise, your module is definitely not independent. The implementation in your module must be called by other modules. At this time, you 'd better generate a header file (H file). In the header file, you can declare that your functions are public. When other modules contain your header file, you can use your public declaration.

7 floor:
A c corresponds to an H, which facilitates management.
For example, if you have a "feed_dog.c", add another "feed_dog.h ":

# Ifndef _ feed_dog_h
# DEFINE _ feed_dog_h

Extern void feed_dog (void );

# Endif

In fact, writing a function in the H file does not matter, but it does not conform to the habit. It doesn't matter how many times an H file is added as long as it is written in the above format.

Floor 8:
Just a convention
In the compiler ,. C and. H is no different ,. C and. h. How to Use it depends entirely on programmers. However, for the sake of future understanding of your program and understanding by others, please abide by the general conventions. The previous conventions have already been discussed a lot.
This is just like a car moving to the right on the road. It is an agreement that the car (compiler) itself does not know whether it is moving to the left or right.
If you like it, you can also use any suffix to name the source file and header file. However, this may cause a strike in the integrated compilation and debugging environment, so you have to write the MAKEFILE file by yourself.

9th floor:
Thank you very much, but I am getting confused now.
1. When a function is frequently used (such as using a dozen C files), I usually put it in the H file and add _ inline. for the _ inline function, many c files can include this h file, but it seems that it can only be included by one H file. If there are two H files include it, a compilation error will occur.
2. The size of some array variables can be up to a dozen K, and the initial value must be assigned, which will not be placed in the C file.
3,
# Ifndef _ feed_dog_h
# DEFINE _ feed_dog_h

Extern void feed_dog (void );

# Endif
Mohanwei, do you think this way? This feed_dog.h can be included countless times?

11 floor:
# Ifndef _ feed_dog_h // if no macro "_ feed_dog_h" has been defined so far
# DEFINE _ feed_dog_h // defines the macro "_ feed_dog_h ".

Extern void feed_dog (void); // declare an external Function

# Endif // "# ifndef" ends here

Therefore, no matter how many times you define (even if you define multiple times in the same c file), there will be no conflict.


I saw an article about. h and. C on the Internet. I feel good. I have posted a post to share it with you.


Simply put
In fact, to understand the differences between the c file and the header file, you must first understand the working process of the compiler. Generally, the compiler will perform the following processes:
1. preprocessing phase
2. Lexical and syntax analysis phase
3. In the compilation phase, the compilation is first compiled into a pure Assembly statement, and then compiled into a CPU-related binary code to generate each target file.
4. In the connection phase, locate the absolute address of each segment of the Code in each target file to generate executable files related to a specific platform. Of course, you can use objcopy to generate binary files only.
Code, that is, the file format information is removed.

The compiler is compiled in units of C files. That is to say, if a c file in your project does not exist, your project cannot be compiled, and the connector is in the unit of the target file.
It migrates functions and variables to one or more target files to generate the final executable files. Generally, there is a main function in program development on PC, which is the main function of each compiler.
Of course, if you write your own connector script, you can use the main function as the program Portal !!!!

With this basic knowledge, let's get down to the truth. In order to generate a final executable file, we need some target files, that is, the C file, and these C files need another main file.
Function as the entry to the executable program, we start with a C file, assuming that the content of this c file is as follows:
# Include <stdio. h>
# Include "mytest. H"

Int main (INT argc, char ** argv)
{
Test = 25;
Printf ("test... % d \ n", test );
}

The header file content is as follows:
Int test;

The following example shows how the compiler works:
1. preprocessing phase: the compiler uses the c file as a unit. First, read the c file and find that the first and second sentences contain a header file. Then, the two files will be searched in all search paths.
File. After the file is found, the corresponding header file will be processed in the corresponding macro, variable, function declaration, nested header file inclusion, etc., check the dependency, macro replacement, to see if there are repeated Definitions
And the declaration occurs. Finally, all the things in those files are scanned into the current c file to form an intermediate "C File"

2. During the compilation phase, in the previous step, the test variable in the header file is scanned into an intermediate C file, and the test variable is changed to a global variable in the file.
Allocate space for all the variables and functions in the intermediate C file, compile each function into a binary code, and generate the target file according to the specific target file format.
And the symbolic descriptions of the functions. These binary codes are organized into a target file according to certain standards.

3. In the connection phase, the target files generated in the previous step are connected to generate the final executable files based on some parameters. The main task is to relocate the functions and variables of each target file.
Is equivalent to combining the binary codes in a target file into a file according to certain specifications.


Return to the topic of the C file and header file:
In theory, the content in the C file and header file can be written no matter what it is supported by the C language. For example, if you write the function body in the header file, as long as this is included in any c file
The header file can compile this function into a part of the target file (the compilation is in the unit of a C file. If this header file is not included in any c file, this code will be virtually empty.
), You can declare functions, variables, and struct in the C file. This is not a problem !!! So why do we need to split the file into a header file and a C file? Why are they generally headers?
Function, variable declaration, macro declaration, struct declaration? What about variable definition and function implementation in file C ?? The reason is as follows:

1. if a function body is implemented in the header file, if it is referenced in multiple C files and multiple C files are compiled at the same time, connect the generated target file to an executable file
In each target file generated by the C file that references this header file, there is a code for this function. If this function is not defined as a local function, then during connection, will be sent
If multiple identical functions exist, an error is returned.

2. if a global variable is defined in the header file and an initial value is assigned to the global variable, a copy of the same variable name will also exist in multiple C files that reference this header file. The key is that this variable is
The initial value is assigned, so the compiler will put this variable into the data segment. Eventually, In the connection phase, multiple Identical variables will exist in the data segment, it cannot unify these variables into one variable, that is, allocate only one space for the variable, instead of multiple spaces. Assume that the variable has no initial values assigned to the header file, the compiler will put it into the BSS segment, and the connector will
Only one bucket is allocated for variables with the same name.

3. if the macro, struct, and function are declared in file C, I need to reference the corresponding macro and struct in another file C, and I have to repeat the work again, if I change a C
If you forget to change the Declaration in other C files, the program logic becomes unimaginable, if you put these public stuff
In a header file, if you want to use its c file, you only need to reference one !!! This is not convenient. to modify a declaration, you only need to change the header file.

4. declare struct and functions in the header file. When You Need To encapsulate your code into a library to allow others to use your code, you do not want to publish the source code, how can people use your database?
What about it? That is, how to use the functions in your database ?? One method is to publish the source code, and others can use it whenever they want to use it. The other is to provide header files that others can see from the original file.
Function prototype, so that people know how to call the function you write, just as you call the printf function, what are the parameters in it ?? How do you know ?? Not looking at people
!!! Of course, these things have become C standards. Even if you don't look at the header files, you can know how to use them.


What is the difference between the ". H" file and the ". c" file in the program source code ??
In the source code of a program, I saw the UDP. h file and the UDP. c file. I don't know what the relationship between the two is? What is the difference? Thank you for your help.

First-level optimal answer. c is the source file of the C language series, which exists in the form of text. the H series is the header file, that is, the file that stores functions and global variables in the C series. Because the functions in C are encapsulated, the Code cannot be seen.

Relationship between header files and implementation files
I have read an article on the Internet explaining. h and. C (. cpp). After reading this article, I feel that something is wrong. I would like to give some guidance to beginners ~
Do you understand simple meanings?
The relationship between the two was about N years ago ~ Long long ago, once aupon a time .......
It was a forgotten time when the compiler only knew. C (. cpp) files, but did not know what. h was.
At that time, people wrote a lot. C (. CPP) files, gradually, people found in many. C (. CPP) the statement in the file is the same, but they have to repeat the content into each word. C (. CPP) file. But what's even more frightening is that when one of the statements changes, you need to check all the. C (. cpp) files and modify the statements in them ~ It's the end of the world!
Finally, some people (maybe some people) can no longer endure this kind of torture. They extract the repeated parts and put them in a new file. C (. CPP. In this way, even if a declaration has changed, you do not need to look for and modify it everywhere-the world is so beautiful!
Because this new file is often placed in the header of the. C (. cpp) file, it is named "header file" with the extension. h.
From then on, the compiler (actually a pre-processor) will know that in addition to the. C (. cpp) file, there will also be a. h file, and a # include command.

Although there were many changes later, this usage has continued for a long time, and people forgot why.

When it comes to header files, let's talk about its role ~
I think of a brief description of the role of header files in high quality C/C ++ programming written by Lin Rui GG:
(1) Use the header file to call the library function. In many cases, the source code is inconvenient (or inaccurate) to publish to users, as long as the header file and binary library are provided to users. You only need to follow the interface declaration in the header file to call the library function, without worrying about how the interface is implemented. The compiler extracts the corresponding code from the library.
(2) the header file can enhance the type security check. If an interface is implemented or used in a different way than the declaration in the header file, the compiler will point out an error. This simple rule can greatly reduce the burden on programmers to debug and correct errors.


Preprocessing is a precursor to the compiler. It integrates program modules stored in different files into a complete source program.
# Include itself is just a simple file containing pre-processing command, that is, put the file after include here, In addition, there is no other use (at least I also think ).


I agree with Brother Qian Kun's point of view. The basic Dongdong must be clear.
The following is an example of Qian Kun's smiling brother. It's time to complete some of his puzzles ~

Example:
// A. h
Void Foo ();


// A. C
# Include "A. H" // my question is: is this sentence necessary or not?
Void Foo ()
{
Return;
}

// Main. c
# Include "A. H"
Int main (INT argc, char * argv [])
{
Foo ();
Return 0;
}

For the above Code, please answer three questions:
Is the # include "A. H" statement in A. C redundant?
1. Why do I often see XX. h corresponding to include in XX. C?
2. If a. C is not written, will the compiler automatically bind the content in the. h file to the. c file with the same name?
3. I changed the third question for him: If. C does not write include <>, then the compiler will automatically set. H files with the same name. are C files bound together?

The following is what Qian Kun said with a smile:

From the perspective of the C compiler, both. h and. C are clouds, and the change to .txt).doc is not big. In other words, there is no bound relationship between. h and. C .. H usually contains the declaration of variables, arrays, and functions defined in the. c file of the same name. The declaration must be used externally by. C. What is the purpose of this statement? Just to make it easier to reference those declarations. Because the macro # include "XX. H" actually means to delete the current row and insert the contents of XX. h In the current row intact. Since there are a lot of places to write these function declarations (every call xx. in C, all functions should be declared before use), so use # include "XX. H "This macro simplifies a lot of line of code-let the Preprocessor replace itself. That is to say, XX. h actually only needs to write xx. in C, where the function declaration is called (a few lines can be written), as for include. who is the H file? Yes. h or. c, it's still with this. h. c, there is no inevitable relationship.
In this way, you may say: ah? So I usually only want to call a function in XX. C, but include the XX. h file. Isn't there a lot of useless declarations after macro replacement? Yes, it does introduce a lot of garbage, but it saves you a lot of pen and ink, and the entire layout looks much refreshed. The fish and the bear's paw cannot be used at the same time. There are more declarations (. H is generally used only for declaration, but not definition. For more information, see "cross the road, around and around"), which will not affect compilation. Why not?
Let's look back at the three questions above. Is that a good answer?

The answer is as follows:
Answer: 1. Not necessarily. This example is obviously redundant. However, if. the functions in C also need to call the same. other functions in C. c usually includes the same name. h. In this way, you do not need to worry about the Declaration and call sequence (the C language requires that the statement must be declared before use, and the include name is the same. H is usually placed in. c ). Many projects even regard this writing Convention as code standards to produce clear code.
2. Answer: 1 has already answered.
3. Answer: No. The people who ask this question are definitely confused, or they want to get confused. What I hate very much is that many of the exams in China are such bad questions, for fear that others will have a clear concept, and they will definitely confuse the candidates.

Over!

Specifically, the compiler is compiled according to the compilation unit. The so-called compilation unit refers to. c file and all. h file. the most intuitive understanding is a file. A project can contain many files. There is a program entry point, which is what we usually call main () function (of course, the program can still start without this function. For details, see my blog ). without this program entry point, the compilation unit only generates the object file (. o file, which is called in windows. OBJ ).

This example contains two compilation units,. c, Main. c. According to what I said, in the compilation stage, only generate their respective. o file. this stage does not have any relationship with other files.
The include pre-processing command occurs in the pre-processing stage (the early compilation stage is only a precursor to the compiler ).


. H. C is not necessarily a float cloud. It doesn't make any sense to talk about it without the compiler. Let alone a deeper level. For example, how does the OS start the file, PE Structure (elf in Linux), and so on?
The compiler must first identify this file to compile it. This is the premise. If you change its extension, can your compiler still know it ~ The problem was raised to a higher level, and XX said well ~ I think what Brother XX says is that the two cannot consider the relationship between the two because their names are the same. The names can be casual ~
The connection between the two is due to historical reasons, and the habit of adding people. I don't want anyone to remember so many file names. (For example, a number
If there are more than 30 fields in the table, I think the top is big. Now there are as many as hundreds of fields in the table. I really hope the senior man can work out some good methods ~, And make our world better ~)

The third question of Qian Kun's smile is very representative. I have seen on the Internet many times that the current compiler is definitely not so intelligent, and it is not necessary to do that. next we will talk about the processing of the compiler. (I think this is where beginners have doubts about the compilation process. h. C (. CPP) is not familiar with the changes ,)

Let me give you a simple example ~
Example:
// A. h
Class
{
Pubic:
Int F (INT t );
};

// A. cpp
# Include "A. H"
Int A: F (int t)
{
Return T;
}

// Main. cpp
# Include "A. H"
Void main ()
{
A;
A. F (3 );
}
In the preprocessing phase, the Preprocessor reads this file when it sees # include "File Name". For example, it compiles main. CPP, see # include ". H ", it will put. h reads the content. It knows that there is a Class A that contains a member function f. This function accepts an int-type parameter and returns an int-type value. It is easy to understand this line of a after compilation. It knows that the Class A is used to generate an object on the stack. Next, it knows that the member function f of A is to be called below, and the parameter is 3, because it knows that this function requires an integer parameter, and this 3 exactly matches, put it on the stack and generate a command to call the F (INT) function (generally a call). Where is the F (INT) function, it does not know, it is left empty, and the link is resolved. It also knows that the F (INT) function will return an int, so maybe it is ready for this (In the example, we didn't use this return value, maybe it won't process it ). Next, compile main. cpp at the end of the file and generate main. obj. You do not need to know the contents of a. cpp during the compilation process.
Similarly, the compiler will compile a. cpp again, compile the F () function, and compile a. cpp without worrying about anything else. Just compile F. A. obj is generated.
The last step is the link stage. The linker links all. OBJ generated by. cpp in the project,
In this step, it defines the address of the implementation of the F (INT) function, and fills in the correct address in the address location left empty in Main. obj. The final Executable File main.exe is generated.

Do you understand? If you don't understand it, let's say a few more words. When learning the compilation principle, we all know that the compiler is implemented in stages. Each stage converts the source program from one representation to another, generally, the order is as follows: source program> lexical splitter> syntax analyzer> semantic analyzer> intermediate code generator> code optimizer> code generator> Target Program.
These 6 activities involve two main activities: The symbol manager and error processor.
The root cause is that there is a stuff called the symbol table, which makes you confused. In fact, the symbol table is a data structure. a basic function of the compiler is to record the identifiers used in the source program and collect various attribute information related to each identifier. the attribute information table shows the storage location, type, and scope of the identifier (valid at that stage). Generally speaking, when the compiler sees a symbolic declaration, for example, your function name will put it in this symbol table for registration ~ The symbol table stores the entry address, number of parameters, and returned information of your function ~ In the connection stage, the relationship between the symbol table and the call is mainly handled, that is, the commonly referred solution reference.
After the previous steps, I do not know whether it is clear or not?

Finally, let's take a look at the end of xxx's three points:
It is easy to understand the syntax and concepts, and it is difficult to explain them. TIPS:
1. Don't get dizzy at work. Take the time to think and read more books;
2. read books and read good books. Ask strong people. Bad books and bad people will give you a wrong concept and mislead you;
3. Diligence and self-help are good training, and it is a hard job;

If you think. C and. the H file is just a bit of a different name. in the history of OP, the development of language tends to be similar to OOP .. the appearance of the H file. the nature of some classes is inside .. hware is concealed. this principle is not hard to find. as long as C's own. see the H file. therefore, I agree that xxx believes that Qian Kun's smile is superficial.

However, from another perspective .:

(As for the implementation of the compiler, I have not yet understood it. However, I believe. Like)
// A. cpp
# Include "A. H"
Int A: F (int t)
{
Return T;
}
This kind of program won't happen... oh, so now people need to understand the simplification of. h and. C. It's also a bit of history and the influence of the times.


The younger brother was dull. After reading it several times, he finally understood it.
Summary: (if there are any errors, please PK)

1. the header file can tell the compiler some necessary statements in advance to make the compiler go smoothly. The actual definition may not appear before the implementation of the connection.
The significance of header files lies in
A. Make the program concise and clear.
B. Avoid writing the same declaration code repeatedly.
2. **. C and **. H files are not necessarily connected.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.