Use of C header files
Let our thoughts go back to the C language teacher on the podium and talk about our first C Language Program: Hello world!
File name First. c
Main ()
{
Printf ("Hello world !");
}
Routine-1
Look at the above program, there is no. h file. Yes, that is, none. Everything in the world has gone through a process that has never been found. We have a certain understanding of. h. I think we also need to start from this step. At this time, we do not need a. h file, because this program is too simple to need. So how can we make it necessary? Let's make this program a little more complex. Please refer to the following,
File name First. c
PrintStr ()
{
Printf ("Hello world !");
}
Main ()
{
PrintStr ()
}
Routine-2
No, so let's make some changes to this program.
File name First. c
Main ()
{
PrintStr ()
}
PrintStr ()
{
Printf ("Hello world !");
}
Routine-3
Wait, but the results are quite different. Let's compile the routine-2.
And routines-3, you will find that routines-3 are not compiled. At this time, we need to understand the concept of another C language: scope.
Here we will only talk about. the top-level scope related to hware. The top-level scope is extended from the declaration point to the end of the source program text. For the printStr () function, there is no separate declaration, only definition, from the defined row to the first. the c file ends, that is, it is already in its scope at the reference point of the main () function in routine-2. the reference point of the main () function in routine-3 is not in its scope, so compilation will fail. what should we do in this situation? There are two methods. One is to let us go back to the routine-2. The order is nothing for us. Who should be the first and then? As long as the program can be compiled and run, let's keep the main () file at the end. let's look at another routine. Let's see if this method works at any time.
File name First. c
Play2 ()
{
...................
Play1 ()
....................
}
Play1 ()
{
..........................
Play2 ()
........................
);
}
Main ()
{
Play1 ()
}
Routine-4
Maybe most of them will be seen. This is a frequently used algorithm with nested functions. Let's see which of the two functions play1 and play2 are in front of each other?
In this case, we need to use the second method and the Declaration.
File name First. c
Play1 ();
Play2 ();
Play2 ()
{
...................
Play1 ()
....................
}
Play1 ()
{
..........................
Play2 ()
........................
);
}
Main ()
{
Play1 ()
}
Routine-4
After a long time of nagging, coupled with the instructions of four routines, we finally began to use quantitative changes caused by qualitative changes, the topic of this Article. H files are coming soon.
A large software project may have thousands or tens of thousands of plays, not just play1 and play2, so there may be N play1 (); play2 (); in this statement, we need to find a way to manage play1 (); play2 (), instead of putting it in. c file, so. the H file appears.
File Name: First. h
Play1 ();
Play2 ();
File name First. C
# Include "first. h"
Play2 ()
{
...................
Play1 ()
....................
}
Play1 ()
{
..........................
Play2 ()
........................
);
}
Main ()
{
Play1 ()
}
Routine-4
You may say that the janders prawn is too long-winded. I also know the above. You have been talking about it for a long time. Please forgive me. If we say that 80% of the people above know it, so I promise that 80% of the people below do not fully know. this is also my consistent style of describing one thing. I always want to clarify one thing so that people who have just come into contact with C can understand it.
The above is the most basic function of the. h file. What other functions does the. h file have? Let me describe a project on hand.
This project has been in operation for more than 10 years. In actual years, no one in our department can say it is inaccurate. Besides, the time is not the most important and we will not go into details. It is the front-end software of a communication device. The source file size is 51.6 MB, the size is 1601 files, and the size is about 10 MB after compilation. It can be imagined that there is a complicated call relationship here, for example, in second. there is another function in c that needs to call first. how to Implement the play1 function in the c file?
Sencond. h file
Play1 ();
Sencond. c file
***()
{
................
Play ();
...................
}
Routine-5
How can I declare the play1 function in the sencond. h file to call the play1 function in the first. c file? Whether it is wrong or not. Here it involves another feature of C language: Storage Class specifiers.
The storage class specifiers in C language include the following:
DescriptionUsage
AutoOnly allowed in Block Variable declaration,Indicates that the variable has a local lifetime.
ExternAppears in the top layer or block external variable functions and variable declarations, indicating declared objects
Has a static lifetime,The Connection Program knows its name.
StaticIt can be placed in the function and variable declaration.When defining a function,It is only used to specify functions
Name,Instead of exporting the function to the Connection Program.In the function declaration,Indicates that
Define declared functions,The storage class is static.In the data declaration,Always indicates Definition
The statement is not exported to the Connection Program.
Undoubtedly, second in routine-5. h and first. in h, we need to use the extern identifier to modify the declaration of the play1 function. In this way, the play1 () function can be exported to the Connection Program, that is, whether in first. the c file is still called in second. c file calls, the Connection Program will be very smart according to our will, connect him to first. the play1 function in the c file does not have to be defined in second. the c file also needs to write the same play1 function.
However, there is a small problem. In routine-5, we didn't use the extern flag to modify play1. Another problem is involved here. The C language has the default Storage Class Identifier. c99 specifies that all top-level default Storage Class Identifiers are extern. so it turns out, haha. think back to the example 4, which is also a good risk. In the case of ignorance, we mistakenly hit it and used the extern modifier; otherwise, we would be in the first. if the play1 function declared in h is not exported by the connected program, we cannot find its actual location when calling play2.
So how can we tell which header file has a declaration defined in its corresponding. c file, and which one does not? This may not be necessary, because no matter which file is defined, the smart Connection Program will help us find it and export it to The Connection Program, but I think it is really necessary. because we need to know what the specific content of this function is and what functions it has. I may want to modify it when new requirements exist. I need to find the definition of this function in a short time, let me introduce the individual rules in C language.:
In. hFunctions declared in the file,IfThe file has definitions,So when we declare this function,Do not use externModifier,If vice versa,The use of extern must be displayed.Modifier.
In this way. in the H file, we will see two types of function declaration. the functions with extern are simple and clear. One is to reference external functions and the other is to define their own life.
The final result is as follows:
Sencond. h file
Extern play1 ();
So many of the above are for functions, but in fact. H files are not used by functions. open one of our projects. in the H file, we found that apart from functions, there are other things, that is, global variables.
In large projects, the use of global variables is inevitable, for example, in the first. c needs to use a global variable G_test. in h, define TPYE G_test. similar to the use of functions, in second. in c, our developers found that they also need to use this global variable, and they need. in c, what should I do? Yes, we can follow the processing method in the function, in second. in h, the TPYE G_test is declared again. According to the use of extern and the default storage type in C Language, The TPYE G_test declared in the two header files is actually extern, that is to say, we don't have to worry about it. The Connection Program will help us deal with everything. but how can we distinguish between global variables, which is definition Declaration and which is reference declaration? This is more complex than the function. It is generally distinguished by the following models in the C language:
1,Initialize statement Model
In the top-level declaration, the initialization statement is yes, indicating that the Declaration is a definition Declaration, and other declarations are reference declarations. COnly one definition Declaration can be found in all language files.
According to this model, we can define the following TPYE G_test = 1 in first. h; then we are sure that the definition declaration is in first, and all other declarations are reference declarations.
2,Omitted storage type description
In this model, all the reference declarations to be displayed include the storage class extern,The storage class specifiers are omitted in the unique definition declaration of each external variable.
This is similar to our method for processing functions.
There is also a need to note that it is not very relevant to this article, but a friend in the previous paragraph encountered this problem. I believe many people will encounter this problem, that is, the global variable of the array.
He encountered the following problems:
When declaring a definition, define an array as follows:
Int G_glob [100];
The reference declaration in another file is as follows:
Int * G_glob;
In vc, it can be compiled. In this case, we are all vague and note that the array is similar to the pointer, but it does not mean that the declared variable for the array is a pointer. The above mentioned program found a problem during runtime. in the file that references the Declaration, when using this pointer, it always prompts a memory access error, in the past, our connection program did not equate pointers with arrays. During the connection, we did not regard them as the same definition. Instead, we thought they were irrelevant two definitions, and of course there would be errors. The correct method is to declare the following in the reference declaration:
Int G_glob [10];
And it is better to add an extern to make it clearer.
Extern int G_glob [10];
In addition, the reference declaration does not need to involve memory allocation, which can be simplified as follows. In this way, when you need to modify the length of the global variable, you do not need to modify all the reference declarations.
Extern int G_glob [];
C language is currently the most widely used language in the underlying core programming. In the past, it will not change much in the future ,. net and other languages and tools have a certain impact on c, but we can see that other languages cannot be replaced in the most important part of the computer, this field is exactly what we yearn for programmers who are obsessed with computers.