C macro definition language skills (commonly used macros)

1, to prevent a file from being included header

#ifndef COMDEF_H

#define COMDEF_H

  // header file content

#endif

2, redefining some types, to prevent a variety of different platforms and compilers, and the difference in the number of type byte is generated to allow transplant.

typedef unsigned char Boolean;. / * Boolean value type * /

 

typedef unsigned Long int UInt32; / * Unsigned 32 'bit value * /

typedef unsigned Short UInt16; / * Unsigned 16' bit value * /

typedef unsigned char uint8; / * Unsigned. 8 'bit * value /

 

typedef int Signed Long Int32; / * Signed 32 'bit value * /

typedef Signed Short Int16; / * Signed 16' bit value * /

typedef char Signed int8; / * Signed. 8 'bit value * /

 

 

// the following deprecated

typedef  unsigned char     byte;         /* Unsigned 8  bit value type. */

typedef  unsigned short    word;         /* Unsinged 16 bit value type. */

typedef  unsigned long     dword;        /* Unsigned 32 bit value type. */

 

typedef  unsigned char     uint1;        /* Unsigned 8  bit value type. */

typedef  unsigned short    uint2;        /* Unsigned 16 bit value type. */

typedef  unsigned long     uint4;        /* Unsigned 32 bit value type. */

 

typedef  signed char       int1;         /* Signed 8  bit value type. */

typedef  signed short      int2;         /* Signed 16 bit value type. */

typedef  long int          int4;         /* Signed 32 bit value type. */

 

Signed Long sint31 typedef; / * Signed 32 'bit value * /

typedef Signed Short sint15; / * Signed 16' bit value * /

typedef char Signed sint7; / * Signed. 8 'bit value * /

 

. 3, to give a byte at the specified address or word

#define MEM_B (X) (* ((byte *) (X)))

#define MEM_W (X) (* ((* word) (X)))

. 4, selecting the maximum value and the minimum value

   #define MAX (x , the y-) (((the X-)> (the y-)) (the X-):? (the y-))

   #define MIN (the X-, the y-) (((the X-) <(the y-)) (the X-):? (the y-))

5 to give a field offset structure (struct) in

#define the FPOS (type, field) /

/ * * lint -e545 / ((DWORD) & ((type *) 0) -> field) / * lint E545 * + /

. 6, a structure to obtain the number of bytes occupied by the field

#define fsiz (type, field) the sizeof (((type *) 0) -> field)

. 7, in accordance with the format of two bytes LSB conversion a Word

FLIPW #define (ray) ((((Word) (ray) [0]) * 256) + (ray) [. 1])

. 8, according to a LSB Word format into two bytes

#define FLOPW (ray, Val) /

  (ray) [0] = ((Val) / 256); /

  (ray) [. 1] = ((Val) & 0xFF)

. 9, to obtain the address of a variable (word width)

#define B_PTR (var) ((byte *) (void *) & (var))

#define W_PTR (var) ((word *) (void *) & (var))

10, to obtain a high and low byte of the word

#define WORD_LO (xxx ) ((byte) ((Word) (XXX) & 255))

#define WORD_HI (XXX) ((byte) ((Word) (XXX) >> 8))

. 11, returns a nearest larger than 8 X multiple

#define RND8 (X) ((((X) +. 7) /. 8). 8 *)

12 is, the uppercase letters to a

#define UPCASE (c) ((( c)> = 'a' && (c (c)): 0x20) - ) <= 'z') ((c)?

numeral 13, 10 is not determined character values into

#define DECCHK (c) ((c )> = '0' && (c) <= '9')

number 14, is not determined character hexadecimal value

#define HEXCHK (c) ((( c)> = ' 0 '&& (C) <='. 9 ') || /

                       ((C)> =' A '&& (C) <=' F. ') || /

((C)> =' A '&& (C) <= 'F'))

15, a method of preventing overflow

? #define INC_SAT (Val) (Val = ((Val) + 1'd> (Val)) (Val) + 1'd: (Val))

16, returns the array element number

#define ARR_SIZE (a) (the sizeof ((a)) / the sizeof ((a [0])))

. 17, returns an unsigned value of n number of tail 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 is, in the configuration for the spatial mapping IO memory space, input and output processing

  #define InP (Port) (* ((volatile byte *) (Port)))

  #define INPW (Port ) (* ((volatile word * ) (port)))

  inpdw #define (Port) (* ((volatile DWORD *) (Port)))

   

  #define OUTP (Port, Val) (* ((volatile byte *) (Port)) = ((byte) (Val)))

  # outpw DEFINE (Port, Val) (* ((* volatile Word) (Port)) = ((Word) (Val)))

  #define outpdw (Port, Val) (* ((DWORD * volatile) (Port)) = ((DWORD) (Val)))

[2005-9-9 add] 

19, using some macros trace debug

ANSI standard describes the five predefined macro names. They are:

_ LINE _

_ FILE _

_ DATE _

_ the TIME _

_ _ STDC

if the compiler is not a standard, it may only support a few more macro name or do not support. Remember that the compiler

may also provide other predefined macro names.

_ LINE _ and _ FILE _ macro has been discussed in the section on # line, the rest of the macro names discussed here.

_ D AT E _ macro containing the form of month / day / year string representing the source file is translated to the date code.

Translation source code to object code string contained in the time as the TIME _ in _. String form hours: minutes: seconds.

If the implementation is the standard, the macro _ STDC _ contain a decimal constant 1. If it contains any other number, the implementation is

non-standard.

Macros can be defined, for example:

when _DEBUG defined, the output data information and the line where the files are located

#ifdef _DEBUG

#define debugmsgto (MSG, DATE) the printf (MSG); the printf ( "% D% D% D", DATE, _LINE_ , _FILE_)

#else

      #define debugmsgto (MSG, DATE) 

#endif

 

20 is, prevent the use of macros is wrong

with containing parentheses.

For example: #define ADD (a, b) (a + b)

with the do {} while (0) comprises a plurality of statements to prevent erroneous statement

example: #difne the DO (A, B) A + B; /

                   A ++;

application: if (. ...)

          the dO (A, B); // error

        else

         

solution: #difne dO (a, b) do {a + b; /

---------------------------------------------------------------------------------------------

Macro "#" and "##" usage
a general usage
we use the # macro argument into a string, with the two macro parameters ## bonded together.
Usage:
#include <cstdio>
#include <climits>
the using namespace STD;

#define the STR (S) #s
#define CONS (A, B) int (## A E ## B)

int main ()
{
    the printf (the STR (VCK)); // output string " VCK "
    the printf ("% D
", CONS (2,3)); // 2E3 output: 2000
    return 0;
}

Second, when the macro when the macro is another parameter
to be noted that in all of useful macros '#' or '##' where the macro parameters are no longer deployed.

1, non '#' and '##' is
#define the TOW (2)
#define the MUL (a, B) (a * B)

the printf ( " D = D *%%% D
", the TOW, the TOW, the MUL (the TOW, the TOW));
This macro will be expanded to the line:
printf ( "% d% d =% d *
", (2), (2), ((2) * (2)));
MUL in the parameters TOW will be expanded as (2).

2, when the '#' or '##' when
#define A (2)
#define the STR (S) #s
#define CONS (A, B) int (## A E ## B)

the printf ( "int max:% S
", the STR (INT_MAX)); // INT_MAX #include < climits>
this line will be expanded as:
the printf ( "int max:% S
", "INT_MAX");

the printf ( "% S
", CONS (A, A)); // the compile error 
this line is:
the printf ( "% S
", int (the AeA));

INT_MAX a and will no longer be expanded, however, a solution to this problem is simple intermediate layer Cadogan conversion macro.
plus this layer is intended to all the macro macro parameters expand all in this layer, you will be able to get the correct conversion macros in macro argument that a macro (_STR).

#define A           (2)
#define _STR(s)     #s
#define STR(s)      _STR(s)          // 转换宏
_CONS #define (A, B) int (## A E ## B)
#define CONS (A, B) _CONS (A, B) conversion macro //

the printf ( "int max:% S
", the STR (INT_MAX)); // INT_MAX, int type, the maximum value for a variable #include <climits>
output: int max: 0x7FFFFFFF
the STR (INT_MAX) -> _STR (0x7FFFFFFF) is then converted to a string;

the printf ( "% D
", CONS (A, A));
output: 200 is
CONS (A, A) -> _CONS ((2), (2)) -> int ((2) E (2))

Third, the '#' and '##' in some applications a special case
1, the merger anonymous variable names
#define ___ anonymous1 (of the type, var, Line) Line ## of the type var
#define __ANONYMOUS0 (of the type, Line) ___ anonymous1 (of the type, _anonymous, Line)
#define aNONYMOUS (of the type ) __ANONYMOUS0 (type, __LINE__)
Example: ANONYMOUS (static int); i.e.: static int _anonymous70; 70 represents the line number;
The first layer: ANONYMOUS (static int); - > __ANONYMOUS0 (static int, __LINE__);
second layer: -> ___ ANONYMOUS1 (static int , _anonymous, 70);
a third layer: -> static int _anonymous70;
i.e. can only unlock current macro layer, the second layer __LINE__ to be solved;

2, filling structure
#define fILL (a) {a,} #a is

enum {the IDD the OPEN, the CLOSE};
typedef struct {the MSG
  the IDD ID;
  const char * MSG;
} the MSG;

the MSG the _msg [] = {FILL (the OPEN), FILL (the CLOSE)};
corresponds to:
the MSG the _msg [] = {{the OPEN, "the OPEN"},
              {the CLOSE, "the CLOSE"}};

. 3, the log file name
#define _GET_FILE_NAME (F) #f
#define GET_FILE_NAME (F) _GET_FILE_NAME (F)
FILE_NAME char static [] = GET_FILE_NAME (__ FILE__);

. 4, to obtain a value corresponding to the character string type buffer size
#define _TYPE_BUF_SIZE (type) the 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 [the sizeof "0x7FFFFFFF"];
corresponds here:
char buf [. 11];

Reproduced in: https: //my.oschina.net/dake/blog/196817

Guess you like

Origin blog.csdn.net/weixin_33958366/article/details/91508529