The relationship between the header file and the source file in C language

Source: Internet
Author: User
Tags function prototype

In fact, to understand the difference between a C file and a header file (i.e.. h), it is necessary to understand the compiler's work process, in general the compiler will do the following procedures:


1. Preprocessing phase
2. Lexical and grammatical analysis phase
3. Compile phase, first compiled into a pure assembly statement, and then compiled into a CPU-related binary code, generate each target file (. obj file)
4. The connection phase, the individual target files in each section of the code for absolute address positioning, to generate a specific platform-related executables, of course, the final can also be used to generate pure binary code objcopy, that is, the removal of file format information. (Generate. exe file)

The compiler is compiled in the C file as the unit, that is, if your project in a C file is not, then your project will not compile, the connector is in the target file unit, it will be one or more target files for function and variable relocation, generate the final executable file on the PC program development, Generally have a main function, which is the Convention of the various compilers, of course, if you write your own connector script, you can not use the main function as a program entrance!!!!

(Main. c File target file executable file)

With these basics, and then, in order to generate a final executable file, you need some target files, that is, c files, and these C files need a main function as an executable program entrance, then we start from a C file, assuming that the C file content is as follows:
#include
#include "Mytest.h"

int main (int argc,char **argv)
{
Test = 25;
printf ("test.................%d/n", test);
}

The contents of the header file are as follows:
int test;

Now let's take this example to explain the compiler's work:
1. Pre-processing stage: The compiler to c file as a unit, first read the C file, found that the first sentence and the second sentence contains a header file, will be in all search paths to find the two files, after finding, will be the corresponding header file processing macros, variables, function declarations, nested header file contains, etc., Detection of dependencies, macro substitution, to see if there is a duplicate definition and declaration of the situation, and finally all those files in all the things scanned into the current C file, the formation of an intermediate "C file"


2. During the compilation phase, the equivalent of the test variable in the header file is scanned into an intermediate C file in the previous step, then the test variable becomes a global variable in this file, then all the variables of this intermediate C file, function allocation space, compile each function into binary code, according to the special Set the target file format to generate the target file, in this format of the target file in the various global variables, functions of the symbolic description, these binary codes according to a certain standard organized into a target file

3. Connection stage, the previous step genetic the various target files, according to some parameters, the connection to generate the final executable file, the main task is to relocate the various target file functions, variables, etc., equivalent to the binary code in a target file according to a certain specification into a file and then go back to the C file and the header file what to write within Capacity of the topic: In theory, c files and the contents of the header file, as long as the C language support, no matter what can be written, such as you write the function body in the header file, as long as any of the C file contains this header file can be compiled into a part of the target file (compilation is in C file units, If you do not include this header file in any c file, this code will be the same as a dummy, you can in C file function declaration, variable declaration, struct declaration, this is not a problem!!! Then why do you have to split the header file with the C file? Why do functions, variable declarations, macro declarations, and struct declarations generally be performed in the first piece? And in the C file to do variable definition, function implementation?? The reasons are as follows:
1. If a function body is implemented in the header file, if it is referenced in more than one C file, and multiple C files are compiled at the same time, the resulting target file is concatenated into an executable file, and in each target file generated by the C file that references the header file, there is a copy of this function code, if this function is not determined is a local function, then when you connect, you will find more than one function, and you will get an error.
2. If the global variable is defined in the header file, and the global variable is assigned the initial value, then there is also a copy of the same variable name in the C file that references this header file, the key is that this variable is assigned the initial value, so the compiler will put this variable into the data segment, and eventually in the connection phase, there will be multiple The same variable, it cannot unify these variables into a variable, that is, to allocate only one space for this variable, not a lot of space, assuming that the variable is not assigned an initial value in the header file, the compiler will put it into the BSS segment, the connector will only allocate one storage space for multiple variables with the same name in the BSS segment
3. If you declare a macro, struct, function, etc. in the C file, then I have to refer to the corresponding macro in another C file, the struct, I have to do another duplication of work, if I changed a C file in a declaration, then forgot to change the other C file declaration, this does not have a big problem, the logic of the program becomes You can not imagine, if you put these common things in a header file, want to use its C file only need to quote one on OK!!! This is not convenient, to change a statement, only need to move the first file on the line
4. Declare the structure, function, etc. in the header file, when you need to encapsulate your code into a library, let others use your code, you do not want to publish the source, then how do people use your library? How do you use each function in your library? One way is to publish the source code, how others want to use it, the other is to provide a header file, others see your function prototype from scratch, so that people know how to call the function you write, just as you call the printf function, what is the parameters inside? How do you know that? Not to look at someone else's head file of the relevant statement AH!!! Of course, these things have become the C standard, even if you do not look at someone's head file, you can know how to use

Confusion in C language. C and. h files

There is no difference in nature. Just General:
The. h file is a header file that contains function declarations, macro definitions, struct definitions, and so on. c files are program files, including function implementations, variable definitions, and other content. And it doesn't matter what the suffix is, except that the compiler will take some action on some of the suffixes by default. You can force the compiler to edit any suffix file as a C file.

It is a good programming style to write two files in such a separate way.


And, let's say I define a declaration of a function in Aaa.h, and then I build aaa.c in the same directory in Aaa.h, AAA.C defines the implementation of this function, and then it's in the main function. c File # # # # # # # # # # # # # # # # # # of Aaa.h Then I can use this function. At run time, main will find the AAA.C file that defines the function. This is because: the main function is the program entry for standard C/s + +, and the compiler will first find the file where the function resides. Assuming the compiler compiles MYPROJ.C (which contains main ()), it is found to include mylib.h (which declares the function void Test ()). The compiler will then look for an implementation file with the same name (with the extension. cpp or. c, in this case, MYLIB.C), based on the pre-defined path (Include path list and the path of the code file), if the file is found and found in the function (in this case, void Test () ), the implementation code continues to compile, and if no implementation is found in the specified directory, or if the implementation code is not located in the file and in subsequent include files, a compilation error is returned. In fact, the process of include can be "regarded as" a file splicing process, The Declaration and implementation are written in header files and C files, or both in the header file, in theory there is no essential difference. The above is called dynamic mode. For static mode, the basic all-in-C + + compiler supports a link method called static link, which is called statically linked. In this way, all we have to do is write the header file that contains the declarations of functions, classes, and so on (A.h,b.h,... ), and their corresponding implementation file (A.cpp,b.cpp,... ), the compiler compiles it into a static library file (A.lib,b.lib,... )。 In the subsequent code reuse process, we only need to provide the corresponding header file (. h) and the corresponding library file (. lib), so we can use the past code. In the relative dynamic way, the advantage of static mode is to realize the concealment of code, that is, the "interface is not visible to the outside world" advocated in C + +. Facilitates the forwarding of library files. c files and. h Files Concepts and linkages
If the hardest part of the puzzle is the basic concept, there may be a lot of people who disagree, but in fact it does. When I was in high school to learn physics, the teacher grabbed the focus is the concept-the concept must be clear, so the problem has become an easy problem. If you can analyze a physical problem there are several physical processes, each of which follows the laws of physics (such as momentum conservation, Bovine II law, Conservation of energy), then it is easy to list the equation of the process according to the law, n process must be n-n-ary equation, the problem will be solved. Even in high school physics competitions, the hardest part is:

(1), confusing your concept, so that you can not analyze a few physical processes, or a physical process to follow the laws of physics;
(2), the existence of equation, the list of equations can not be solved. The latter is already a category of mathematics, so the hardest part is to master the clear concept;

The same is true of program design, if the concept is clear, it is basically no problem (it will be difficult in mathematics, such as the choice of algorithms, time space and efficiency, stability and balance of resources). But it's not that easy to master a clear concept. For example, see if you have a clear and thorough understanding of this.

A.h
void Foo ();

A.c
#include "a.h"//My question came out: this sentence is to, 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:

A.C in the #include "a.h" This sentence is not redundant?
Why do you often see the xx.c include corresponding xx.h?
If A.C is not written, then does the compiler automatically bind the contents of the. h file with the. c file of the same name?
(Please carefully consider the above 3 questions for 10 minutes, MO should be anxious to see the explanations below.) :) The more you think about it, the deeper you will understand. )

Okay, TIME's up! Please forget the 3 questions above and your thoughts on these three questions, and then listen to me slowly. The correct concept is: from the C compiler point of view,. h and. C are clouds, that is, the name of. txt,. doc is not a big difference. In other words, the. h and. C Have nothing to do with it. The declarations of variables, arrays, and functions defined in the. c file with the same name are generally placed in H. Declarations that need to be used externally by. C. What's the use of this statement? Just make it easy to quote where these statements are needed. Because #include "xx.h" this macro its actual meaning is to delete the current line, the contents of the xx.h is inserted in the current line position intact. Because there are so many places to write these function declarations (every call to a function in XX.C is declared all at once), a macro that uses #include "xx.h" simplifies many lines of code--and lets the preprocessor replace itself. In other words, xx.h actually just makes the call where the function declaration in the XX.C needs to be written (fewer lines can be written), as for the include. h file who, is it. h or. c, or the. h with the same name. C, there is no inevitable relationship.
So you might say, "Ah?" I usually just want to call a function in xx.c, but include the Xx.h file, is not a macro replacement after a lot of useless declarations? Yes, it does introduce a lot of rubbish, but it saves you a lot of ink, and the whole layout looks more refreshing. It is this truth that the fish and bear cake cannot be combined. Anyway, more statements (. h is generally only used to put the declaration, but not defined, see my book fixing "cross the road, look Around") also harmless, do not affect the compilation, why not?
Turn back and look at the top 3 questions, very good answer it?

Answer: not necessarily. This example is obviously superfluous. But if the functions in. c also need to call the same. C, then this. C will often include. h with the same name, so that there is no need to worry about the order of declarations and calls (the C language requires that it must be declared before it is used, and include has the same name.) h is usually placed at the beginning of. C. There are many projects that even use this notation as code specifications to standardize clear code.
Answer: 1 has already answered.
Answer: No. The person who asks this question is definitely unclear, or wants to mix water to touch fish. Very annoying is a lot of Chinese test out of this bad problem, for fear that others have a clear concept, absolutely to the examinee dizzy.
It is easy to understand grammar and concept, and it is difficult to say difficult. The trick has three points:

Do not dizzy head work, take the time to think more, read more books;
Read books to be optimistic, ask people to ask the strongman. Bad books and rotten people will give you a wrong concept, misleading you;
Qinnengbuzhuo is good training, a point of hard work only;

(1) The library function is called through the header file. In many cases, the source code is inconvenient (or not) to the user, as long as the user is provided with a header file and a binary library. The user only needs to invoke the library function according to the interface declaration in the header file, without having to worry about how the interface is implemented. The compiler extracts the appropriate code from the library.
(2) header file can enhance type safety check. If an interface is implemented or used in a way that is inconsistent with the declaration in the header file, the compiler will point out the error, a simple rule that can greatly reduce the burden of debugging and error-changing by the programmer.
The header file is used to store function prototypes.

How does the header file relate to the source file?

The problem is actually that the known header file "A.h" declares a series of functions (only function prototypes, no function implementations), and "b.cpp" implements these functions, so if I want to use "a.h" in "c.cpp" to declare these functions in "b.cpp", it is usually in the " C.cpp "Use # include" A.h ", then C.cpp is how to find the implementation of B.cpp?
In fact, there is no direct relationship between the. cpp and. h file names, and many compilers can accept other extensions.
In the book "C Program Design", rectification mentioned that when the compiler preprocessing, the # include command is "file contains processing": Copies the entire contents of Headfile.h to the # include "Headfile.h". This also explains why many compilers do not care what the suffix of this file is----because the # include preprocessing is a "copy and insert Code" work.
When the program compiles, it does not look for the function implementation in the B.cpp file, but only when the link is done. We use # include "A.h" in B.cpp or c.cpp to actually introduce the relevant declaration, so that the compilation can pass, the program does not care where the implementation is, how it is implemented. The source file is compiled into a target file (. o or. obj file), and these functions and variables are treated as symbols in the destination file. At Link, It is necessary to indicate in makefile which. o or. obj file (here is the. o or. obj file generated by b.cpp), at which point the connector will go to the. O or. obj file for functions implemented in b.cpp and build them into the executable file specified in makefile.
In the VC, a bunch of situations do not need to write their own makefile, just need to be included in project files, VC will automatically help you write makefile.
Typically, the compiler will look for the required symbols in each. o or. obj file, instead of just looking in a file or finding one. Therefore, if you implement the same function in several different files, or if you define the same global variable, the link will prompt "redefined".

This article from Csdn Blog, reproduced please indicate the source: http://blog.csdn.net/shi_869160/archive/2010/07/03/5710441.aspx

========================================= Split Line ===============================================

Read the notes:

Simply understand that the C file contains header file relationships to directly insert the contents of the header file in the appropriate location.

When you define a function body or variable in a header file, if you have more than one C file referencing this file, you will get a duplicate definition of the function or variable error.

The workaround is to add the static keyword before the function so that there is no error. In this way, each C-file compilation unit will have the compiler code for the function body and will not appear

The redefinition error is because the static keyword restricts the scope of the function to this C file, which is obviously very foolish, and it only makes sense of the principle.

Example code:

TEST.C file:

#include "test.h"

int add (int a, int b)
{
return a+b;
}

Test.h file:

int add (int a, int b);

static int sub (int a, int b)
{
return a-B;
}

MAIN.C file:

#include <stdio.h>

#include "test.h"

int main (void)
{
printf ("A + b =%d\n", add (6, 2));
printf ("A-B =%d\n", Sub (6, 2));
}

Add and sub Two functions are defined, add is in test.c, and sub in Test.h, these two functions are called in MAIN.C.

There is nothing wrong with the static keyword in front of the sub function.

When the keyword is removed, the compilation results are as follows:

Static has a different effect on local variables and global variables. For local variables, it changes the variable from dynamic storage to a static storage mode.

For global variables, it makes the variables localized (local to this file), but is still stored in a static manner. From the scope point of view, where there is static

Declared, its scope is limited, or confined to this function (static local variables), or confined to this file (static external variables).

Functions are global in nature, so use static to qualify their scopes.

c, the relationship between the header file and the source file (go)

Related Article

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.