1. Basic form

#define name replacement_text 
Copy the code

Typically, the #define directive is on one line, and the replacement text is all of the rest of the bottom of the define directive, but it is possible to divide a long macro definition into several lines, requiring a backslash at the end of the line to be continued.

Macro definitions can also take parameters so that different replacement text can be used for different macro calls. Ex. :

#define max(A, B) ((A) > (B) ? (A) : (B)) 
Copy the code

2. Pitfalls in macro expansion

If you think carefully about the expansion of Max, the expression is evaluated twice, so if the expression contains behavior such as an increment operator or input/output, it will be incorrect, such as the macro Max above:

max(i++, j++)  // wrong 
Copy the code

It is also important to note that parentheses are used properly to ensure the correct order of calculations, for example:

#define	square(x)	x * x	// wrong 
Copy the code

An error occurs when the macro definition is called with square(z+1).

3. #undef

In the header

, the getchar and putchar functions are often defined as macros in practice to avoid the runtime overhead of calling functions when processing characters. The functions defined in the

header are also often implemented via macros.

The macro definition of the name can be undefined by #define, which ensures that subsequent calls are function calls rather than macro calls:

#undef getchar

int getchar(void) {... }Copy the code

4. Macro parameters,## #

If the parameter name is prefixed with # in the macro definition’s replacement text, the result is extended to replace the quoted string of the actual parameter. For example, you can combine it with a string concatenation operation to write a debug print macro:

#define	dprint(expr)	printf(#expr " = %gn", expr) 
Copy the code

Use the statement

dprint(x/y); 
Copy the code

When called, the macro is extended to:

printf("x/y" " = %gn", x/y); 
Copy the code

The strings are concatenated so that the effect of the macro call is equivalent to

printf("x/y = %gn", x/y); 
Copy the code

The preprocessor operator ## provides a means of concatenating actual parameters for macro extensions. If an argument in the replacement text is adjacent to ##, the argument is replaced by the actual argument, the whitespace before and after ## is removed, and the replacement result is rescan. For example, the following macro paste is defined to join two parameters:

#define paste(front, back)	front ## back 
Copy the code

Therefore, the result of a macro call to paste(name, 1) will establish the token name1.


References:

  1. Brian W. Kernighan, Dennis M. Ritchie.The C Programming Language (Second Edition)[M]. China Machine Press: Beijing,2004:76-77.