C language Macro definition tips (common macro definitions)
Write good C language, beautiful macro definition is important, using macro definition can prevent errors, improve portability, readability, convenience and so on. The following is a list of some mature software commonly used macro definitions ...
1, prevents a header file from being repeated included
#ifndef Comdef_h
#define Comdef_h
Header file Contents
#endif
2. Redefine some types to prevent differences in the number of types of bytes produced due to different platforms and compilers, which facilitates portability.
typedef unsigned char Boolean; /* Boolean value type. */
typedef unsigned long int uint32; /* Unsigned-bit value */
typedef unsigned short uint16; /* Unsigned-bit value */
typedef unsigned char uint8; /* Unsigned 8 bit value */
typedef signed Long int int32; /* Signed-bit value */
typedef signed short Int16; /* Signed-bit value */
typedef signed CHAR int8; /* Signed 8 bit value */
The following is not recommended for use
typedef unsigned char byte; /* Unsigned 8 bit value type. */
typedef unsigned short word; /* unsinged-bit value type. */
typedef unsigned long DWORD; /* Unsigned-bit value type. */
typedef unsigned char uint1; /* Unsigned 8 bit value type. */
typedef unsigned short Uint2; /* Unsigned-bit value type. */
typedef unsigned long uint4; /* Unsigned-bit value type. */
typedef signed Char Int1; /* Signed 8 bit value type. */
typedef signed short Int2; /* Signed-bit value type. */
typedef long int int4; /* Signed-bit value type. */
3 to get a byte or a word on the specified address
#define MEM_B (x) (* (BYTE *) (x))
#define MEM_W (x) (* ((Word *) (x)))
4, maximum and minimum values are calculated
#define MAX (x, Y) (((x) > (y))? (x): (y))
#define MIN (x, Y) (((x) < (y))? (x): (y))
5, gets the offset of a field in the struct (struct)
#define STRUCT_MEN_POS (Type,member) (unsigned int) & ((type *) 0)->member
6, get the number of bytes occupied by field in a struct
#define FSIZ (type, field) sizeof (((type *) 0)->field)
7, convert two bytes into a word in LSB format
#define FLIPW (Ray) (((Word) (Ray) [0]) + (Ray) [1])
8, convert a word to two bytes in LSB format
#define FLOPW (Ray, Val) \
(Ray) [0] = ((val)/256); \
(Ray) [1] = ((val) & 0xFF)
9, get the address of a variable (word width)
#define B_PTR (Var) ((BYTE *) (void *) & (Var))
#define W_PTR (Var) ((Word *) (void *) & (Var))
10, get a word of high and low byte
#define WORD_LO (XXX) ((byte) ((WORD) (XXX) & 255))
#define WORD_HI (XXX) ((byte) ((WORD) (XXX) >> 8))
11, returns a multiple of the nearest 8 that is larger than X
#define RND8 (x) (((((x) + 7)/8) * 8)
12, convert one letter to uppercase
#define UPCASE (c) (((c) >= ' A ' && (c) <= ' Z ')? ((c)-0x20): (c))
13, determine if the character is a number that is 10 in value
#define DECCHK (c) ((c) >= ' 0 ' && (c) <= ' 9 ')
14, determine if the character is a number that is 16 in value
#define HEXCHK (c) (((c) >= ' 0 ' && (c) <= ' 9 ') | | \
((c) >= ' A ' && (c) <= ' F ') | | \
((c) >= ' A ' && (c) <= ' F '))
15, one way to prevent overflow
#define INC_SAT (val) (val = (val) +1 > (val))? (val) +1: (val))
16, returns the number of array elements
#define ARR_SIZE (a) (sizeof ((a))/sizeof ((a[0)))
17, returns the value of an unsigned N-tailed Mod_by_power_of_two (X,n) =x% (2^n)
#define Mod_by_power_of_two (val, mod_by) \
((DWORD) (VAL) & (DWORD) ((mod_by)-1))
18, for IO spatial mapping in the storage space structure, the input and output processing
#define INP (Port) (* (Volatile byte *) (port))
#define INPW (Port) (* (volatile word *) (port))
#define INPDW (Port) (* (volatile DWORD *) (port))
#define OUTP (Port, Val) (* (Volatile byte *) (port)) = ((Byte) (val)))
#define OUTPW (Port, Val) (* (volatile word *) (port)) = ((Word) (val))
#define OUTPDW (Port, Val) (* (volatile DWORD *) (port)) = ((DWORD) (Val)))
19, use some macro tracking debugging
A N S I standard describes five predefined macro names. They are:
_ L I N E _
_ F I L E _
_ D A T E _
_ T I M E _
_ S T D C _
If the compilation is not standard, only a few of the above macro names may be supported, or not supported at all. Remember to compile the program
Other predefined macro names may also be available.
_ L i n e _ and _ F I l e _ macro instructions are discussed in the section on # L i n E, where the remaining macro names are discussed.
_ D at E _ macro contains a string in the form of a month/day/year, indicating the date when the source file was translated to the code.
The time the source code is translated into the target code is included as a string in _ T I M E _. The string form lasts: minutes: seconds.
If the implementation is standard, then the macro _ S T D C _ contains the decimal constant 1. If it contains any other number, the implementation is
Non-standard.
You can define macros, for example:
When the _DEBUG is defined, the output data information and the file where the
#ifdef _DEBUG
#define DEBUGMSG (msg,date) printf (msg);p rintf ("%d%d%d", Date,_line_,_file_)
#else
#define DEBUGMSG (Msg,date)
#endif
20, macro definition prevents use is wrong
enclosed in parentheses.
Example: #define ADD (A, B) (a+b)
Use the Do{}while (0) statement to contain multiple statements to prevent errors
Example: #difne do (A, b) a+b;\
a++;
When applied: if (...)
Do (A, b); Error generated
Else
Workaround: #difne Do (A, b) do{a+b;\
a++;} while (0)
Usage of "#" and "# #" in macros
I. GENERAL usage
We use # To change the macro argument to a string with # #把两个宏参数贴合在一起.
Usage:
#include <cstdio>
#include <climits>
using namespace Std;
#define STR (s) #s
#define CONS (A, b) int (a# #e # #b)
int main ()
{
printf (STR (VCK)); Output string "Vck"
printf ("%d\n", CONS (2,3)); 2E3 Output: 2000
return 0;
}
Second, when the macro parameter is another macro
It is important to note that the macro parameter, where the macro definition is useful ' # ' or ' # # ', is no longer expanded.
1, non-' # ' and ' # # ' situations
#define TOW (2)
#define MUL (A, B) (a*b)
printf ("%d*%d=%d\n", TOW, TOW, MUL (Tow,tow));
This line of macros will be expanded to:
printf ("%d*%d=%d\n", (2), (2), ((2) * (2)));
The parameter tow in the MUL will be expanded to (2).
2, when there is ' # ' or ' # # '
#define A (2)
#define STR (s) #s
#define CONS (A, b) int (a# #e # #b)
printf ("int max:%s\n", STR (Int_max)); Int_max #include <climits>
The Guild is expanded to:
printf ("int max:%s\n", "Int_max");
printf ("%s\n", CONS (A, a)); Compile error
This line is:
printf ("%s\n", int (AeA));
Int_max and A are no longer being unfolded, but the solution to this problem is simple. Add an extra layer of intermediate conversion macros.
The intention of adding this layer is to expand all the macro parameters in this layer, then the macro (_STR) in the macro can get the correct macro parameters.
#define A (2)
#define _STR (s) #s
#define STR (s) _str (s)//Convert macro
#define _cons (A, b) int (a# #e # #b)
#define CONS (A, B) _cons (A, B)//CONVERT macro
printf ("int max:%s\n", STR (Int_max)); Maximum value of type Int_max,int, for a variable #include <climits>
Output is: int max:0x7fffffff
STR (Int_max)--_STR (0x7fffffff) and then convert to string;
printf ("%d\n", CONS (A, a));
Output is: 200
CONS (A, a)-_cons ((2), (2))-Int ((2) E (2))
Third, ' # ' and ' # # ' Some of the application exceptions
1. Merging 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__)
Example: ANONYMOUS (static int); That is: static int _anonymous70; 70 indicates the line number of the row;
First layer: ANONYMOUS (static int); --__ANONYMOUS0 (static int, __line__);
Second layer:--___ANONYMOUS1 (static int, _anonymous, 70);
Third layer:--static int _anonymous70;
That is, you can only unlock the current layer of macros, so __line__ in the second layer can be untied;
2. Filling structure
#define FILL (a) {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. Get a string buffer size corresponding to a numeric 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 to:
Char buf[11];
Go C Language Macro Definition Tips