Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
First point out that the compiler we usually refer to is not just a compiler, but rather a compilation tool chain that includes a precompiled compiler, a compiler, a assembler, and a connector.
For external function entities (functions in a source file other than the one in which the function is called), they are searched and added to the program during the link process, and once the function entity is not found, the error is not successfully linked.
The declaration of an external function (which is generally declared in the header file) simply makes the program run smoothly through compilation, and does not need to search for entities for external functions.
Of course, the source file where the external function entity resides also needs to be compiled into the target file, which is done by the linker as to how to find the function entity when linking.
In addition, the naming of the header file and the corresponding source file is not necessarily related.
Here's an online blog post:
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.
header file How to associate source files ?
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?
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" by the
Rectification, the compiler preprocessing involves "file containment" of the # include command: Copies the entire contents of Headfile.h to # 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 is compiled, it does not look for the function implementation in the B.cpp file, only to do this work on link. 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 want to include the required files are included in project, VC will automatically help you write the makefile well.
Typically, the compiler finds 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".
Questions about external function calls in the C language