Basic Explanation This section mainly explores a range of common programming issues caused by the characteristics of the two aspects of the C compiler. Compiling C files: C program is usually composed of several small programs (.c files), the compiler compiles these small programs, and then combines them together to form a target code together via the linker. Since the compiler can only compile a file each time, it cannot immediately check the error that requires several source files to find. Establishing a temporary variable C compiler to establish a temporary variable C compiler for the function of the function, which can also pass a pointer to the function's return value. Because these temporary variables have the existence of implies, in some cases, in particular, it will lead a series of problems when they exist. The header file contained in the C file is compiled with the C language.
The header file included in the C language is compiled with the .C file, the problem in the header file is reflected in the compilation of the .C file. Question: Compilation of C files
I have an array a defined in F1.c, but I want to calculate the number of elements in F2.c, can I achieve this with SIZEOF?
Answer and analysis:
The answer is negative, you have no way to achieve the purpose, the reason is that the sizeof operator works just "Compile Time", and the compilation unit of the C language is compiled each time. C file (other languages are also in this way). Therefore, SIZEOF can determine the size of an array in the same source file, but it is incomplete to the array defined in another source file, because it is already "run time" to determine what is determined.
One thing to do, there will always be a way, and there are three optional methods to solve this problem:
1), define a global variable, let it remember the size of the array, in another .C file we get the size information of the array by accessing this global variable (it seems to be a little small matter to do not pay for the loss ^ _ ^).
2), in a .h file, macro define the size of the array, such as #define array_size 50, and then contain this .h file in the two source files, get the definition in different .c files by directly accessing array_size. The size of the array.
3), set the last element of the array for special values, such as 0, -1, null, etc., then we look for this special end element by traversing an array, thus judge the length of the array (which is less efficient, but also stupid ).
Question: Function return value implies the pass pointer
The following code can work normally, but there is a fatal error generation at the end of the program. what is the root cause?
Struct List {char * item; struct list * next;}
Main (argc, argv) {...}
Answer and analysis:
The reason is very simple, and it is difficult to find that it can solve this problem after the right bruces behind the defined structure.
Struct list {char * item; struct list * next;}; // missing this semicolid!
Ok, the problem is solved, but do you know what a fatal problem is this error? The problem is not as simple as the surface, OK, let us take a look at the truth behind things.
First take a look at the code below:
Void func (struct my_struct stx) {.......} struct my_struct stand = {...}; func (style);
When the modulus function is called, the value of the structural variable STY is copied into the calling stack, so as the parameter is passed to the function func, this called C language parameter value is passed. I believe this must be very clear, then you should know: How should the function return to the call if the return value of the function is structural variables? And look at the following code: struct my_structfunc (void) {.......} struct my_struct stand = func ();
At this time, the return value of the function FUNC is a value of a structural type. This return value is placed in a dark and horrible place in memory, while arrangeing a pointer to this place (temporarily called "mysterious pointer"), and this pointer The compiler by the C language is passed to the function func as a hidden parameter. When the function func returns, the code generated by the compiler copies the value of the memory area of the hidden pointer to the return structure STY to complete the return structure variable value to the caller.
You understand the above-mentioned stuff, then today's real reasons are coming out:
Because the definition of struct list {...} does not add a bit number, it is caused by the main function main (argc, argv) to be a function of a return value as a structural variable, which is desirable to obtain the first except for Argc and Argv. Three parameters, that is, the "mysterious pointer" that we mentioned above. However, everyone knows that the function is the main function, and the parameter of the main function is provided by the startup code in the program. The startup code, of course, main () is born to get two parameters, to "mysterious pointer", of course, this () main () is returning to the self-propelled self-emptive to visit its access to it does not exist The third parameter (ie, mystery pointer), which leads to illegal access to produce fatal problems. This is the true root of this problem.
Suggest:
1) Try to try to use the pointer of the structural variable instead of the structure itself as a function parameter, otherwise the overhead of the memory copy is not small, especially for those frequent, structural body.
2) After the structure definition must be added to the same number, after the above paragraph tells, I believe you will not make the same mistake.
Question: The compiler will impose a temporary copy of the parameters of the function.
What kind of results do you have to run the following Test function?
Void getMemory2 (char ** p, int num) {* p = (char *) malloc (num);}
Void Test (void) {char * str = null; getMemory (& STR, 100); STRCPY (STR, "Hello"); Printf (STR);}
Answer and analysis:
This is the example of Lin Rui's "C / C High Quality Programming Guide", which is used.
This call will generate the following two consequences:
1), able to output Hello
2), memory leakage
Another related question:
What kind of results will there be a Test function?
Void getMemory (char * p) {p = (char *) malloc (100);
Void test (void) {char * str = null; getMemory (STR); STRCPY (STR, "Hello World"); Printf (STR);}
Answer and analysis:
The consequences are serious, the result is the result of the program, and we can see by running the debug. We can see that after getMemory, the STR in the Test function is still NULL. It is conceivable that StrCPY (STR, "Hello World") is called.
The program will inevitably collapse.
Cause Analysis:
The C compiler will always make temporary copies for each parameter of the function. The copy of the pointer parameter P is _P, the compiler makes _p = P. If the program in the function is modified, the contents of the parameter P are modified accordingly. This is why the pointer can be used as an output parameter. In this example, _P applies for new memory, just changing the memory address referred to in _P, but p is unchanged. So the function getMemory does not output anything. If you want to output dynamic memory, use the pointer to the pointer, or use the pointer to the reference.
Question: The header file and the .C file containing it compiled together
The following code is very short, it seems unpleassed, but the compiler will report a mistake. Where can I appear?
#include "someheader.h" int myint = 0;
Answer and analysis:
Don't stare at int myint = 0; see that this assignment should be the simplest statement in the C language. The problem will definitely not appear on it, then the problem can only appear in someHeader.h, the most common thing is the header file The last line of statement (the function is good, the variable is also good) has no semicolon ";" ending, then the compiler will combine it with myint variables, naturally it will be wrong.
This problem is mainly reminding you that ideas should be wanncted when positioning problems, and may consider whether there is a problem with the header files.
Conclusion: The header of the included header is compiled with the .C file, the problem in the header file will be reflected in the .C file compilation, remember.