About those things before the executable program

  • When we were writing the code, I wonder if everyone, like me at the beginning, just run the code with CTRL+F5? ? At the beginning, I only knew that an .exe executable file would be generated, and I didn't know the middle principle at all.
  • Today, I will lead you to have a deeper understanding of generating executable files.

  •  The translation environment and execution environment of the program

  • In any implementation of ANSI C, there are two distinct environments.
  • The first is a translation environment, where source code is converted into executable machine instructions. The second is the execution environment which is used to actually execute the code.
  •  Each source file that makes up a program is individually converted into object code by the compilation process.
  • Each object file is bundled together by the linker to form a single, complete executable program.
  • The linker also imports any standard C library functions used by the program, and it can search the programmer's personal library and link the functions it needs into the program.

  • Translation is also divided into several processes:

  •  In preprocessing, we can use gcc text.c -E -o text.i in the Linux environment to see what the compiler does in preprocessing
  •  We found that just 10 lines of code became more than 700 lines. This is because the included header files are expanded and macros have been replaced during preprocessing.
  • Here, have you ever thought about a question? ? In the preprocessing stage, should the macro replacement be executed first or the comment should be executed first? ? ?

 

 

  •  After proof, we found that the comment removal is executed first. If the macro replacement is executed first, then there will be no Hello World output.

  • Predefined symbols:

  • _FILE_ //The source file for compilation
  • _LINE_ //The current line number of the file
  • _DATE_ //The date the file was compiled
  • _TIME_ //The time when the file was compiled
  • _STDC_ //If the compiler follows ANSI C, its value is 1, otherwise it is defined

The definition of macros is essentially replaced in the preprocessing stage.

  • Let's look at this code and we will know that we defined SQUARE with a macro. If I didn't say that the essence of macro is replacement, many people would think that the answer is 36. After what I said above, the essence of macro is replacement, so it is replaced with printf("%d\n",5+1&1+5); this, the answer is 11  
    #define SQUARE(x)  x*x
    int main()
    {
    	int a = 5;
    	printf("%d\n", SQUARE(5 + 1));
    
    	return 0;
    }

     


  • Advantages of macros:

  •  The code used in and returned from a function may take more time than it takes to actually perform this small computational work, so macros are superior to functions in terms of program size and speed.
  • The second is that macros are type-independent
  • Disadvantages of macros:

  • Macros cannot be recursive and are not easy to debug
  • Parameters may be substituted in multiple places in the macro body, so parameter evaluation with side effects may produce unexpected problems

    To sum up, I actually recommend using functions, which can be debugged, and using inline in C++ also combines the advantages and disadvantages of macros and functions.


naming convention

 Macro names are all capitalized, function names are not all capitalized


  • command line definition
  • In many C compilers there is a capability that allows symbols to be defined on the command line. Used to start the compilation process. For example: this feature is somewhat useful when we want to compile different versions of a different program based on the same source file. (Suppose an array of a certain length is declared in a program. If the machine memory is limited, we need a small array, but another machine memory is capitalized, and we need an array that can be capitalized.)
  • For example, the following code I use the command line definition

 


Common Preprocessing Directives 

  • #ifndef 
  • #define
  • #if
  • #endif
  • #elif
  • ...
  • Of course, there are many preprocessing instructions, which will not be described here.

  • Among the preprocessing instructions here, the common ones we have are
  • #ifndef include <stdio.h>
  • #define include <stdio.h>
  • #endif 
  • This is to prevent the header file from being included repeatedly. As mentioned in our first figure, the header file will be expanded during preprocessing, so there will be more than 700 lines of code in the text.i file
  • Of course #pragma once can also prevent header files from being included repeatedly

  • Finally: Let me tell you that in large-scale projects, header files and definitions are always separated, and #include "text.h" or #include <filename.h> will be used. Let me talk about the differences between them.

  • In fact, they are just different search strategies. The search strategy of #include "filename.h" is to search in the directory where the source file is located. If the compiler cannot be found, it will search for the library function header file in the standard location. Compile error if not found

  • And #include <filename.h> is to directly find the header file in the standard location of the library function header file

Guess you like

Origin blog.csdn.net/m0_72165281/article/details/131798001