1. prevent a header file from being repeatedly contained
# Ifndef bodydef_h
# Define bodydef_h
// Header file content
# Endif
2. Get a byte or word on the specified address.
# Define mem_ B (x) (* (byte *) (x )))
# Define mem_w (x) (* (word *) (X )))
3. Get the offset of a field in the struct (struct ).
# Define FPOs (type, field) (DWORD) & (type *) 0)-> field)
4. Obtain the number of bytes occupied by the field in the struct.
# Define fsiz (type, field) sizeof (type *) 0)-> field)
5. Get the address of a variable (word width)
# Define B _ptr (VAR) (byte *) (void *) & (VAR ))
# Define w_ptr (VAR) (word *) (void *) & (VAR ))
6. convert a letter into uppercase letters.
# Define upcase (C) (c)> = ''a' & (c) <= ''z '')? (C)-0x20): (c ))
7. judge whether the character is a decimal number.
# Define decchk (C) (c)> = '0' & (c) <= '9 '')
8. determines whether the character is a hexadecimal number.
# Define hexchk (C) (c)> = '0' & (c) <= '9') | (c)> = ''a' & (c) <= ''f'') | (c)> = ''a'' & (c) <= ''f ''))
9. A method to prevent overflow
# Define inc_sat (VAL) (val = (VAL) + 1> (VAL ))? (VAL) + 1: (VAL ))
10. returns the number of array elements.
# Define arr_size (A) (sizeof (a)/sizeof (A [0])
11. Use some macro tracking for debugging
The ANSI standard specifies five predefined macro names:
_ Line _ (two underscores), corresponding to % d
_ File _ corresponds to % s
_ Date _ corresponds to % s
_ Time _ corresponds to % s
_ Stdc _
Usage of "#" and "#" in macro:
Use # To convert macro parameters into a string, and use # to combine two macro parameters.
# Define STR (s) # s
# Define cons (a, B) int (A ## e ## B)
Printf (STR (vck); // output string "vck"
Printf ("% d \ n", cons (2000); // 2e3 output:
When the macro parameter is another macro:
Note: Where the macro definition is useful for "#" or "#", macro parameters will not be expanded.
# Define a (2)
# Define STR (s) # s
# Define cons (a, B) int (A ## e ## B)
Printf ("% s \ n", cons (A, A); // error: 'aea 'was not declared in this scope
Printf ("% s \ B", STR (int_max); // int_max
Int_max and a will not be expanded. The solution to this problem is simple: add another layer of intermediate conversion macro.
The purpose of adding this macro layer is to expand all macro parameters in this layer. Then, the macro (_ Str) in the conversion macro can get the correct macro parameters.
# Define STR (s) _ STR (s) // convert macro
# Define cons (a, B) _ cons (a, B) // convert a macro
Printf ("int MAX: % s \ n", STR (int_max); // The maximum value of int_max, int type, is a variable # include <climits>
The output is: int MAX: 0x7fffff, that is, STR (int_max) --> _ STR (0x7fffffff) and then converted to a string;
Printf ("% d \ n", cons (A, ));
Output: 200, that is, cons (a, a) --> _ cons (2), (2) --> int (2) E (2 ))
Some application cases of "#" and "#"
1. Merge anonymous variable names
# Define ___ anonymous1 (type, VAR, line) type var # Line
# DEFINE _ anonymous0 (type, line) ___ anonymous1 (type, _ anonymous, line)
# Define anonymous (type) _ anonymous0 (type, _ line __)
For example, anonymous (static INT); that is, static int _ anonymous70; 70 indicates the row number;
First layer: anonymous (static INT); --> _ anonymous0 (static int, _ line __);
Layer 2: --> ___ anonymous1 (static int, _ anonymous, 70 );
Layer 3: --> static int _ anonymous70;
That is, the macro of the current layer can only be unlocked at each time, so _ line _ can be unlocked at the second layer;
2. fill Structure
# Define fill (a) {A, #}
Enum IDD {open, close };
Typedef struct MSG {
Idd id;
Const char * MSG;
} MSG;
MSG _ MSG [] = {fill (open), fill (close )};
Equivalent:
MSG _ MSG [] = {open, "open "},
{Close, "close "}};
3. Record File Name
# DEFINE _ get_file_name (f) # F
# Define get_file_name (f) _ get_file_name (f)
Static char file_name [] = get_file_name (_ file __);
4. Obtain the buffer size of the string corresponding to the value type.
# DEFINE _ type_buf_size (type) sizeof # type
# Define type_buf_size (type) _ type_buf_size (type)
Char Buf [type_buf_size (int_max)];
--> Char Buf [_ type_buf_size (0x7fffffff)];
--> Char Buf [sizeof "0x7fffffff"];
This is equivalent:
Char Buf [11];