| C Preprocessor & Macro |
| |
| Macro substitution directives |
| |
| We have already met this facility, in its simplest form it allows us to define textual substitutions using #define statement. |
| |
| The #define statement can be used for more, however, than simply defining symbolic constants. |
| |
| In particular, it can be used to define macros; its, single identifiers that are equivalent to expressions, complete statement or groups of statements. Macros resemble function in this sense. |
| |
| They are defined in an altogether different manner than functions, however, and they are treated differently during the compilation process. |
| |
| Format: #define identifier string |
| |
| e.g.: #define MAXSIZE 256 |
| |
| This will lead to the value 256 being substituted for each occurrence of the word MAXSIZE in the file. |
| |
| Example: |
| |
 |
| |
| Out put of the program |
| |
 |
| |
| This program contains the macro area, which represents the expression length* width. |
| |
| When the program is compiled, the expression length * width will replace the identifier area within the printf statement, so that printf statement will become |
| |
| Printf("\narea =%d", length *width); |
| |
| Note that the format string " \n area =%d" is unaffected by the #define statement. |
| |
| When the program is executed, the values for length and width are entered interactively from the keyboard, and the corresponding value for area is displayed. |
| |
| A typical interactive session is shown below. The user's responses are underlined, as usual. |
| |
| Length =_3 |
| Width =_4 |
| Area=12 |
| |
| Macro definitions are customarily placed at the beginning of a file, ahead of the first function definition. |
| |
| The scope of a macro definition extends from its point of definition to the end of the file. However, a macro defined in one file is not recognized within another file. |
| |
| Multilane macros can be defined by placing a backward slash (\) the end of each line except the last. |
| |
| This feature permits a single macro (i.e. a single identifier) to represent a compound statement. |
| |
| Here is another simple c program that contains multilane macro: |
| |
 |
| |
| Out put of the program |
| |
 |
| |
| Macros are sometimes used in place of functions within a program. |
| |
| The use of a macro in place of a function eliminates the time delays associated with function calls. |
| |
| If a program contains many reported function calls, the time savings resulting from the use of macros can become significant. |
| |
| On the other hand, macro substitution will take place whenever a reference to a macro appears within a program. |
| |
| Thus, a program that contains several references to the same macro may become unreasonably long. We therefore face a tradeoff between execution speed and size of the compiled object program. |
| |
| The use of a macro is most advantageous in applications where there are relatively few functions calls but the function is called repeatedly. |
| |
| Using #define to Create Functional Macros |
| |
| #define can also be given arguments which are used in its replacement. The definitions are then called macros. |
| |
| Macros work rather like functions, but with the following minor differences. |
| |
| Since macros are implemented as a textual substitution, there is no effect on program performance (as with functions). |
| |
| Recursive macros are generally not a good idea. |
| |
| Macros don't care about the type of their arguments. Hence macros are a good choice where we might want to operate on reals, integers or a mixture of the two. |
| |
| Macros are full of traps for the unwary programmer. In particular the textual substitution means that arithmetic expressions are liable to be corrupted by the order of evaluation rules. |
| |
| Here is an example of a macro which won't work: |
| |
| #define DOUBLE(x) x+x |
| |
| Now if we have a statement |
| |
| a = DOUBLE(b) * c; |
| |
| This will be expanded to |
| |
| a = b+b * c; |
| |
| And since * has a higher priority than +, the compiler will treat it as. |
| |
| a = b + (b * c); |
| |
| The problem can be solved using a more robust definition of DOUBLE |
| |
| #define DOUBLE(x) (x+x) |
| |
| Here the brackets around the definition force the expression to be evaluated before any surrounding operators are applied. This should make the macro more reliable. |
| |
| In general it is better to write a C function than risk using a macro. |
| |
| |
| |
| |
| |