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
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.
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.
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
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

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.

Post a Comment