C ++ Function Description and definition

Source: Internet
Author: User

The Declaration tells the compiler some information to assist the compiler in syntax analysis and avoid compiler errors. The definition is to tell the compiler to generate some code that will be used by the connector. That is, the Declaration is for compilation
The connector is defined. This description is vague. Why do we have to make a declaration and definition here? This is because C ++ agrees to split the program into several segments, which are written in different files and
The mentioned compiler is compiled only from top down and only once for each file.

When the compiler compiles a program, only the source files are compiled one by one and the corresponding intermediate files are generated separately (for VC. (OBJ file), and then all intermediate files are connected by the connector to form an executable
. The problem is that the compiler is compiling. in the CPP file, the variables A and B are defined in the definition statement, but B is being compiled. CPP, it is found that the code using a and B, such as a ++;, the compiler will
Error. Why? If no error is reported, as defined in A. cpp, how does one compile B. cpp before compiling a. cpp? If the source file compilation sequence is specific, the compilation will be greatly reduced.
Therefore, C ++ stipulates that: Compile. all things (variables, functions, etc.) defined in CPP are compiled in B. when CPP is used, all counts are not counted, and A is not compiled. the same as CPP. So
B. What should I do if CPP uses the variables defined in A. cpp? To this end, C ++ proposed the concept of declaration.
Therefore, the variable declaration long
A; indicates that the compiler already has such a variable. Its name is a and its type is long. Its corresponding address is unknown, but you can mark it first, that is, in the subsequent code, where this variable is used
Mark, to tell the connector to connect, first look for a variable named a in all the intermediate files, the address is, and then modify all the marked places, put the address corresponding to. In this way
This file uses the variables defined in another file.
So declare long
A; it is to tell the compiler that there is such a variable A. Therefore, when using a in subsequent code, do not report an error saying that A is not defined. The same is true for functions, but the difference between function declaration and function definition is very easy,
Since the function definition must be followed by a composite statement, but the variable definition is exactly the same as the variable declaration, how does the compiler identify the variable definition and variable declaration? The compiler encounters a long
A. It is regarded as a variable definition in a unified manner. To identify the variable declaration, the modifier extern proposed by C ++ can be used.
A modifier is used in a declaration or Definition Statement to modify this declaration or definition to provide certain information to the compiler. It is always followed by or after a declaration or definition statement, for example:
Extern long a, * pA, & RA;
The preceding Declaration (not defined) contains three variables A, Pa, and RA. Because extern indicates the external meaning, the above is considered to tell the compiler that there are three external variables, A, Pa, and Ra. Therefore, it is considered as a declaration statement, therefore, no memory is allocated. Similarly, for functions, it is the same:
Extern void ABC (long); or extern long AB (short B );

The above extern is equivalent to not writing, because the compiler can determine the above is a function declaration based on the final ";", and the provided "external" information is meaningless to the function, the compiler will not
Ignore. Extern actually specifies the modifier of the identifier after it is modified. The actual modifier should be extern "C" or extern "C ++", which respectively indicate the C language style and C ++ Language
Style to parse the declared identifier.

C ++ is a strong type language, that is, it requires strict type matching principles, in order to achieve the function overload function described above. That is to say, several functions with the same name can be implemented for overloading, because they are not actually the same name,
The parameter types and numbers are modified to be different. For example, void ABC (), * ABC (long), ABC (long, short
); In VC, their respective names will be changed to "? ABC @ yaxxz ","? ABC @ yapaxj @ Z ","? ABC @ yaxjf @ Z ". While
Extern long a, * pA,
& RA; the names of the three declared variables also change accordingly. A @ 3ja ","? Pa @ 3paja ","? RA @ 3aaja ". The above is called
Identifier modifier of the C ++ language style (different compiler modifier formats may be different ), the identifier modification in the C language style is simply to add "_" before the identifier (the C style modification in different compilers ).
The decoration must be the same ). For example, extern "C" long a, * pA, & RA; is changed to _ A, _ Pa, and _ Ra. The above extern "C"
Void ABC (), * ABC (long), ABC (long, short
); An error will be reported, because the C style is only followed by an underscore before the function name, three identical symbols (Symbol) will be generated.

Why cannot I have the same symbol? Why do I need to change the identifier? Not only is it because of the previous function overload. A symbol is different from an identifier. It can be composed of any character. It is a means of communication between the compiler and the connector,
The identifier is only a means of identification provided at the C ++ language level. The reason why we need to change the identifier instead of using it as a symbol is that the compiler has some information between itself and the connector.
If the information needs to be passed, it must be identified by symbols. Because the identifier written by the user is exactly the same as the one used in the compiler, therefore, you must modify the identifier defined by the programmer before using it.
Symbol. Since all characters can be used as symbols, the compiler does not allow its own internal symbols to use characters that are not usable by identifiers, such as the "?", That's not enough? Because some
The symbols used by the C/C ++ compiler and connector for communication are not any character or must be an identifier, therefore, the prefix of "_" is added in the C language to distinguish between symbols defined by programmers and
The internal symbol of the compiler. That is, you can use "?" As the symbol is VC, maybe other compilers do not support it, but other compilers must support identifiers with the prefix. In this way, you can join
Multi-party code is used to achieve code reuse in a larger scope. This is detailed in C ++ from (18.
When writing extern void ABC (long
); Is extern "C" or extern "C ++ "? In VC, if the source file where the above Code is located has the extension. cpp to indicate that it is C ++ source code, it will be interpreted as the latter.
If it is. C, it will be interpreted as the former. However, in VC, you can modify the default settings by modifying the project options. And extern long a; is the same as above.
Therefore:
Extern "C ++" Void ABC (), * ABC (long), ABC (long, short );
Int main () {ABC ();}

The first sentence above tells the compiler that subsequent code may use these three functions, so that the compiler should not report errors. Assuming that the above program is placed in a. cpp of a VC project, compiling a. cpp will not show any
Error. But when connected, the compiler will say the symbol "? ABC @ yaxxz "is not found, because this project contains only one file, and the connection only connects a. OBJ and other
Necessary library files (will be described later ). The connector searches for the symbol "? What is the address corresponding to ABC @ yaxxz? No
No, so an error is reported. In other words, the main function uses the void defined outside of A. cpp.
ABC ();, but the definition of this function is not found. Note that if it is written as int main () {void (* pA) = ABC;
} An error will still be reported, because ABC is equivalent to an address, and the value of this address must be calculated here (even if Pa is not used), so the same error is reported.
To eliminate the preceding errors, you should define the void ABC () function. CPP, such as after the main function, you can also generate a new one. add the CPP file to the project. the definition function ABC in the CPP file. So you can:
Extern "C ++" Void ABC (), * ABC (long), ABC (long, short );
Int main () {ABC ();} void ABC (){}

If you think you have understood the differences between the Declaration and definition and the meaning of the statement, I bet there is a 50% possibility that you have not really understood the meaning of the statement, due to space limitations
The true meaning of the statement in C ++ from scratch (10). If you are a C/C ++ programmer, the sample given at that time should be 50% likely to surprise you.

 

Description


I have already explained the meaning of declaration. Here, due to the new definition syntax of the member function definition rules, the meaning of declaration must be reconsidered. Note: Put the definition of a function into the main function.
You don't need to declare that function before the definition. If a variable is defined, you don't need to declare that variable. This means that the definition statement has the declaration function, but the Definition Statement of the above member function
But does not have the declaration function. Let's take a look at the true meaning of the Declaration below.

Declaration is a statement that requires the compiler to generate ing elements. The so-called ing element is the variables and functions described earlier. There are only three columns (or three fields): type column, name column, and address bar (member variable type
This column contains the offset value ). That is, the compiler generates a ing element whenever it sees the declaration statement, and leaves the corresponding address bar blank, and then leaves some information to tell the connector -- this. OBJ file (Compiler
The files generated after the source file is compiled. For VC files, some symbols are required. Find these symbols, modify and complete the. OBJ file, and connect them.
In retrospect, the symbol is a string used for communication between the compiler and the connector. Note that the symbol has no type, because the connector is only responsible for finding and perfecting the symbol (because the address bar of some ing elements is still empty. OBJ file), no syntax analysis, there is no type.

The definition requires the compiler to fill in the address bar that was previously declared not written. That is to say, the address corresponding to a variable is only known when it is defined. Therefore, the actual allocation of memory on the stack is completed by the definition of variables.
So declared variables do not allocate memory. Note that the definition is the address required to generate the ing element. Therefore, the definition shows the address of the ing element it generates.
There is no ing element in the ing table of the interpreter (that is, the variable table or function table used to record the ing element in the compiler), that is, no declaration of the corresponding element has been made, the compiler reports an error.

But I only wrote one variable or Function Definition Statement before. Is it still normal and there is no error? Actually, it is very simple. You only need to regard the Declaration and definition as a statement, except that the information provided to the compiler is different.
For example, void ABC (float); and void ABC (float
) {}, The compiler treats them the same. The former provides the function type and type name, so the compiler only fills in the ing element name and type columns. This function is not provided because only ";" is followed.
Therefore, the compiler cannot enter the address bar. The latter provides the function name, type, and ing code (empty composite statement). Therefore, the compiler obtains all the information to be filled in and
When all the information is filled in, the result shows that the definition statement has completed the declaration function.
For variables such as long
A ;. Same as above, the type and name are provided here, so the compiler fills in the two columns: type and name. But the variable corresponds to the first address of a block of memory on the stack. This first address cannot be displayed from the Code (the previous function
Write a composite statement after the function declaration to display the address of the code corresponding to the corresponding function), which must be obtained by computation within the compiler, therefore, it is hard to specify that the above writing is counted as a variable.
To declare a variable, you must add extern in front. That is, the compiler will perform internal computation to get the corresponding address and fill in all the information of the ing element.
It is inevitable that the above seems to be confused because of the emergence of custom types. Consider the definition of member variables, such:
Struct ABC {long a, B; double C ;};
The preceding examples show the types -- long ABC:, long ABC:, and double.
ABC:; name -- ABC: A, ABC: B, and ABC: C; Address (I .e. offset) -- 0, 4, and 8, because it is a structure-type custom type, this statement can
Obtains the offset of each member variable. The above three pieces of information can be filled in all the information of the ing element, so the above can be counted as a Definition Statement. For member functions, see the following:
Struct ABC {void AB (float );};
The preceding example shows the type -- void (ABC:) (float
); The name is -- ABC: AB. However, because no address is provided, you cannot fill in all the information of the ing element. Therefore, the above is the declaration of the member function ABC: AB. As mentioned above, as long
You can give the address, without having to worry about whether it is a definition or declaration, so it can be like this:
Struct ABC {void AB (float ){}};
The type and name are given above, and the address is given at the same time. Therefore, all information of the ing element can be filled in completely, which is the definition. The usage above has its own particularity, which is described later. Note: If the ABC: AB Definition Statement is followed by the following statement, it will be incorrect:
Struct ABC {void AB (float ){}};
Void ABC: AB (float ){}

The above error will be reported for a simple reason, because the latter is only defined, it only provides the ABC: AB address information, but the address bar in the ing element has already been filled in, the compiler will repeat the definition. Again
Let's look at the definition of the member function separately. It provides the void (ABC:) (float
(ABC: AB). Why does it only provide the address? First, the name ABC: AB does not comply with the identifier rules, and the type Modifier
ABC: you must use the type definition character "{}" to add it. This is described multiple times in the previous section. Therefore, the above information is: give an address, which is of the type void (
ABC:) (float
), The address of the ing element ABC: AB. The result compiler looks for such a ing element. If yes, enter the corresponding address bar. Otherwise, an error is reported, that is, only one void is written.
ABC: AB (float
) {} Is incorrect. Before it, you must declare the corresponding ing element through the type definition character. That is, the definition mentioned above only fills the address bar and does not generate ing elements.

Role of statement

The role of definition is obvious. It is used for meaningful ing (name-to-address), but what is the purpose of declaration? It only generates the name of the type pair. Why do we need the name of the type pair? It just tells the compiler not to make an error saying that the variable or function is not defined? Everything has its own meaning. Let's take a look at the following code.
Extern "C" Long ABC (long a, long B );
Void main () {long c = ABC (10, 20 );}
Assume that the above Code is written in a. cpp and the file a. obj is compiled and generated. However, according to the previous instructions, the connection will be incorrect because the symbol _ ABC cannot be found. Because the address bar corresponding to name_abc is still empty. Add a new source file B. cpp to the project where a. cpp is located in VC, and write the following code.
Extern "C" float ABC (float a) {return ;}
Compile and connect. Now there is no problem, but I believe you have seen the problem. -- the declaration of function ABC does not match the defined type, but the connection is successful?

Note that the preceding connection description indicates that there is no connection type, just a symbol. The above uses extern "c" to make a. OBJ require the _ ABC symbol, while B. CPP provides the _ ABC symbol, and the remaining
Only the connector puts the address of _ ABC in B. OBJ into A. OBJ to improve a. OBJ, and finally connects a. OBJ and B. obj.

So what is the above result? Because we need to consider the implementation details of the function, this is explained in "C ++ from the very beginning (15 th)". Here we only need to notice one thing: the compiler can generate a generation even if there is no address.
Code to implement the function of the function operator-function call. This is because the type and name must be given at the same time during declaration, because the type tells the compiler that when an operator involves a ing Element
How to generate code to implement the function of this operator. That is to say, the code generated by the multiplication of two Char Types and the multiplication of two long types is different.
The function call code of ABC (long); is different from that of void ABC (float. That is, the different numeric types used by operators will lead to different code generated by the compiler.

So why should we put the ABC definition in B. cpp? Because the compilation between source files is independent, if it is placed in a. CPP, the compiler will find that such a ing element already exists, but the type is
If it does not match, an error is returned. Put it in B. cpp, so that the connector can improve a. obj. Then there will be no type, just the symbol. Continue.
Struct ABC {long a, B; void AB (long tem1, long tem2); void ABCD ();};
Void main () {abc a; A. AB (10, 20 );}
As mentioned above, although ABC: AB is not defined here, it can still be compiled successfully without any problems. Assume that the above Code is in a. cpp, add B. cpp, and write the following code in it.
Struct ABC {float B, A; void AB (long tem1, long tem2); long ABCD (float );};
Void ABC: AB (long tem1, long tem2) {A = tem1; B = tem2 ;}

The function ABC: AB is defined here. As mentioned earlier, the function definition here is only defined, therefore, you must write the type definition character "{}" before it to let the compiler generate a ing element. But more
Note that the bitwise of the member variables is replaced here, so that B maps 0 and a maps 4, and the types of A and B are changed to float, and. the definition in CPP is quite different. But no
If there is any problem, the compilation connection is successful, A. AB (41200000); after execution, A. A is 0x41a00000, A. B is 0 x, and * (float *
) & A. A is 20, * (flaot *) & A. B is 10.

Why? This is because the compiler only follows type matching in the source file currently compiled, and all the ing elements generated by compiling other source files are invalid when compiling another source file. Therefore, the Declaration binds the type and name
And the name represents the number of the associated Type of the address type, and the compilation of all operators operating on the number in the subsequent code will be affected by the type of the number. That is, the Declaration tells the Compiler
How to generate code is not only a syntax statement that describes variables or functions, it is indispensable.
Note that the ABC: ABCD member functions in the above two files have different declarations, and the entire project (that is,. CPP and B. in CPP) there is no definition of ABC: ABCD, but the connection can still be compiled successfully, because the Declaration does not tell the compiler what is already there, but how to generate code.

Header file


As described above, if there is a custom type ABC. CPP, B. CPP and C. to use it in CPP, it must be in. CPP, B. CPP and C. in CPP, use
Before ABC, use the type definition character "{}" to re-define the custom type. If you accidentally write different definitions in A. cpp and B. cpp as shown in the preceding figure, a difficult-to-find error will occur.
Therefore, C ++ provides a pre-compiled command to help you.

Precompiled commands are the commands executed before compilation. They are interpreted and executed by the Pre-compiler. The pre-compiler is another program. Generally, the compiler vendors merge the program into the C ++ compiler and only provide one program.
. In this example, the precompiled instruction contains the instruction -- # include, in the format of # include
<File Name>. Note that precompiled commands must occupy a single line, and <File Name> is a file name enclosed by double quotation marks or angle brackets, such as: # include
"ABC. c", # include "C:/ABC. DSW" or # include
. Its function is very simple, that is, the file corresponding to the file name written in quotation marks or angle brackets is in ANSI or MBCS format (for details about these two formats, refer to C ++ from scratch (v, and
Replace the content with the # include location, for example, the ABC content of the file.
Struct ABC {long a, B; void AB (long tem1, long tem2 );};
The preceding a. cpp can be changed:
# Include "ABC"
Void main () {abc a; A. AB (10, 20 );}
B. cpp can be changed:
# Include "ABC"
Void ABC: AB (long tem1, long tem2) {A = tem1; B = tem2 ;}
At this time, it will not appear in B. in CPP, the custom ABC definition is written incorrectly, resulting in incorrect results (. A Is 0x41a00000,. B is 0x41200000), and then. AB (10, 20); after execution,. A is 10,. B is 20.

Note that double quotation marks are used to enclose the file name. It indicates that when only one file name or relative path is included and the full path is not given, search for the source file to be compiled.
Directory, and then search for the compiler's customized include directory (such as: C:/program files/Microsoft Visual Studio. NET
2003/vc7/include), which usually contains the header file of the SDK that comes with the compiler (the SDK will be described in "C ++ from (), if not found
(Note: The Compiler generally provides some options so that you can search for the specified directory in addition to the preceding directory. Different compilers have different setting methods, this is not a table ).
If it is enclosed by Angle brackets, it indicates that the self-defined include directory of the compiler is searched first, and then the directory where the source file is located. Why is it different? Only to prevent conflict between the file name and the file name under the compiler's include directory, because once the file is found, the subsequent directory will not be searched.

Therefore, in General C ++ code, if you want to use a custom type, all the custom type definitions are packed in two files respectively. For the above structure ABC, two files should be generated, which are
ABC. h and ABC. cpp are called header files, while ABC. cpp is called source files. The Declaration is put in the header file, while the definition is put in the source file, then the ABC. h
The content is the same as the previous ABC, while the content of ABC. cpp is the same as that of B. cpp. Then, whenever the structure ABC is used in a source file in the project
ABC. H, which is equivalent to bringing all relevant declarations of the structure ABC into the compilation of that file. For example, the previous A. cpp declares the structure ABC by including ABC at the beginning.

Why do we need to generate an ABC. cpp? If the Definition Statement of ABC: AB is also put in ABC. H, A. cpp should use ABC and C. cpp should also use ABC, so
A. CPP contains ABC. H. Because of the definition of ABC: AB in it, a symbol is generated? AB @ ABC @ qaexjj @ Z (for VC); C. cpp compilation is also required.
The connector cannot determine which one to use due to two identical symbols. An error is returned. Therefore, we define ABC. cpp to put the ABC: AB function definition
In ABC. OBJ, only one symbol is generated, and no error is reported during connection.

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.