Network seminar from senior microchip engineers
With regard to the preprocessing of C and its definition of macro, let's look at some extensions of macro correctness and errors, and how to expand them. All the norms are based on the ansi c compiler.
1. Simple macro processing:
# Define name "replacement text"
Example usage:
# Define start 20
Foobar = start;
"Replacement text" can be expanded by other macro definitions
For example:
# Define limit 100
# Define Pref limit
Setting = Pref;
This macro expansion can be extended until there is no macro definition.
2. prevent repeated macros
For example:
# Ifndef LCDH
// Header file contents go here
// Now stop this being encoded ded again
# Define LCDH
# Endif
The scope of this application is from the definition to the end of the module, or the # UNDEF
3. macro definition with Parameters
# Define name (argument-list) Replacement text
The parameter will replace the corresponding items in "replacement text ".
Example usage:
# Define diff (A, B) (a)> = (B )? (A)-(B):-1)
Result = diff (input, 6 );
After expansion:
Result = (input)> = (6 )? (Input)-(6):-1 );
The Preprocessor can replace one or more variable parameters to achieve more complex replacement. To prevent unexpected results, brackets must be added for each replaced variable.
4. String replacement
For example:
# Define product (year) "matrix" # YEAR
Const char * productname = product (2000 );
After expansion:
Const char * productname = "matrix" "2000 ";
Eventually:
Const char * productname = "matrix2000 ";
When the macro definition contains variable parameters, you can use some special operators. One of them is the # operator, which can convert variables into C strings. In this example, after preprocessing, the variable productname will point to the string "matrix2000". In expansion, the two symbols # year are replaced by the variable and the resulting string is connected to the "matrix.
5. Connection Variables
For example:
# Define Blatch (BIT) latb # bit
Blatch (4) = 1;
Replace:
Latb4 = 1;
Another macro operator is "#", which allows you to connect any two symbols, not just strings. In this example, the operator # is used to connect the latb and bit variables. When a replacement is generated, it is extended to latb4, which is the fourth port of latch B of the PIC processor.
This function is useful, but there is a potential problem when the variable itself is another macro that requires pre-processor expansion. Let's look at the following:
# Define Blatch (BIT) latb # bit
# Define motor 4
Blatch (motor) = 1;
Pre-processor
Extended to: latbmotor = 1;
This is obviously not what I want.
The root cause of the problem is that macro variables are not prioritized when they are replaced. The pre-processor defines that a macro variable can be extended only when it is not #, # Or not #. Therefore, when "motor is inserted into" Blatch, it will not be further extended because it is near the # operator.
Fortunately, we found a way to implement this extension:
You can do this in two steps:
# Define paste (a, B) a # B
# Define Blatch (BIT) paste (latb, bit)
# Define motor 4
Blatch (motor) = 1;
Pre-processor:
Latb4 = 1;
The second macro is the extension of the current variable, and the second macro is connected, which realizes the functions we need.
Let's look at the last complex example:
# Define paste2 (a, B) a # B
# Define paste (a, B) paste2 (A, B)
# Ifdef pic18 // set for pic18 Devices
# Define Io lat
# Else
# Define IO port
# Endif
# Define pin 4
# Define rdport paste (port, pin)
# Define rdlatch paste (Io, pin)
# Define ioread (LOC) paste (Rd, Loc)
Usage:
Result = ioread (Latch );
When we understand this example, we will feel a sense of accomplishment, but when you think that this code will work well, you will find a compiler error or other adverse consequences.
The final result is: Result = paste (Lat, 4 );
The reason is that each macro extension can only be implemented once in one expression. The specific process is as follows:
Ioread (Latch)
-> Paste (Rd, latch)
-> Rdlatch
-> Paste (Io, pin)
-> Paste (Lat, 4); labels
The pre-processor does not perform expansion during the second paste extension.
The solution is to write another macro with the same function as paste but different names.