A macro in C language is a piece of code that is given a name. Whenever a name is used, it is replaced by the contents of the macro.

2 Function-like Macros

You can define a macro that is similar to a function call. This is known as function-like macros. To define a function like a macro, we can use the same '#define' command or directive, but you add two parantheses immediately after the macro of name. For example, you can define a macro that is similar to a function call. They are called function-like macros. To define a macro that is similar to a function, use the #define command, but immediately after the macro name, put two parentheses.
for example,
#define tmp_exp() c_exp()
tmp_exp() ==> c_exp()
A function-like macro is extended only by a pair of parentheses earlier its name. If you write only the name, it will stay alone. This can be suitable if you have a function and a macro with the same name and want to use that function from time to time.
extern void func(void);
#define func()
...
func();
ptrfunc = func;
In the example above, the call to func() will use the macro, but the function pointer will have the address of the current function.
If the macro requires expansion, a syntax error will be displayed. If you put a space between the macro name and the parentheses in your macro definition, it will not define a function like macro, but an object like macro that expands from two sets of parentheses.


3 Macro Arguments

Function-like macros can accept the same arguments as real functions. To define a macro that takes arguments, add a parameter to the macro definition, which makes the macro look like a function. Parameters must be legal C identifiers, separated by commas and optional spaces.
To call a macro with arguments, you write the macro name after the main argument names in parentheses separated by commas. A macro invocation is not limited to a single line of arguments - it can be as long as you want in a file. The number of arguments you supply corresponds to the number of parameters in the microdefinition.
When a macro is expanded, each use of its body parameter is substituted by the equivalent argument token. You don’t need to usage all the parameters in the macro body.
Example,
A macro that calculates the minimum of two numeric values, as it is defined in many C programs and some applications.

#define min(X, Y) ((X) < (Y) ? (X) : (Y))
x = min(a, b); ==> x = ((a) < (b) ? (a) : (b));
y = min(11, 12);==> y = ((11) < (12) ? (11) : (12));
z = min(a + 18, *p);==> z = ((a + 18) < (*p) ? (a + 18) : (*p));

Trailing and leading whitespaces in each argument are discarded, and all spaces in the argument token are reduced to a single space.
The parentheses in each argument must be balanced; Such a parentheses comma does not end the argument. However, square brackets or braces are not required for balance, and they do not prevent arguments from being separated by commas.
macro (array[p = q, p + 1])
Two arguments are passed to the macro:
array[p = q and p + 1].
If you want to pass an array [p = q, p + 1] as an argument, you can write it as an array [(p = q, p + 1)], which is equivalent to C code. All macro arguments are fully expanded before being placed in the macro body. After conversion, all text is then checked for macro expansion, including arguments. This rule may look strange, but it is cautiously designed so that you don't have to concern about whether a function call is really a macro call.
However, if you are too smart, you may run into trouble.

Let learn the following example.
min (min (p, q), r) is first expanded to
min (((p) < (q) ? (p) : (q)), (r))
and then to
((((p) < (q) ? (p) : (q))) < (r)
? (((p) < (q) ? (p) : (q)))
: (r))


4 Stringification:
Sometimes you want to translate or convert macro arguments to string constants. Parameters are not transmuted to string constants, but we can use the `#' pre-processing operator instead. When a macro parameter with a leading `#' is used, the pre-processor replaces it with the literal text of the original argument, which is converted to a string constant.
Unlike normal parameter substitution, the first argument is not macro-extensible. This is called stringification.
There is no method to combine the argument with the neighbouring text and stringify it all together. As an alternative, you can write an array of concatenated string constants and stringified arguments. The pre-processor will substitute the stringified argument with string constants. The C compiler will then concatenate all neighbouring string constants into one long string.

C program Demonstrate a macro definition that uses stringification:
#define IF_ WARN(EXP_COND)

do {
  if (IF_ WARN)
     fprintf (stderr, "Warning: " #EXP_COND "\n");
 }while(0)
 IF_ WARN (x1 == 0);
do {
  if (x1 == 0)
   fprintf (stderr, "Warning!: " "x1 == 0" "\n");
 } while (0);

The argument for IF_ WARN is replaced once, as-is, into the if statement, and once, stringified, into the argument to fprintf. If x1 were a macro, it would be extended in the if statement, but not in the string.
The do and while (0) are a kludge to make it possible to write IF_ WARN (arg);, which the similarity of IF_ WARN to a function would make C programmers want to do

5.Concatenation

It is repetitively useful to combine two tokens into one when expanding a macro. This process is called token concatenation or token pasting in C language . The pre-processor Operator `##' pastes the pre-processing operator token. When ever the macro is extended, the two tokens on each side of each `##' operator are combined into a single token, which substitutes `##' and the two original tokens in the macro extension or expansion.
Generally, both are identifiers. or one will be an identifier And the other one will be the pre-executed code. When the code is pasted It will create a long identifier. This is not the only quality problem. Two numbers are likely (or numbers and names, such as 1.5 and E3) are combined into one. You can also create multi-character operators, such as +=, by pasting a token.
Conversely, two tokens symbols that do not form a valid token when added together can be inserted together. For example, you cannot combine x with + in any order. If you try, the executable warns and outputs the two characters as if they were written next to each other. It is common to find redundant use of `## in complex macros. If you get this warning, you can easily remove the '##'.
All characters connected by "##" can be taken from the body of the macro, but you can first write them as a single token at the first place. Token pasting is very useful when one or both tokens come from a macro argument. If one of the characters around ``##'' is the name of a parameter, it is replaced with the original argument before ``##' is executed. As with casting to a string or stringification, the actual argument does not initialize the macro expansion. If the argument is empty, this `## has no effect.
Note that the C preprocessor converts the comments to white spaces before the macros are straight considered. Hence, you cannot make cmment by combining `*' and `/'. You can put as many whitespaces as you like between "##" and its functions, including comments, and also insert comments into arguments that will be concatenated. However, the appearance of the "##" symbol at the end of the macro body is an error.

In this program, we create a new file employee.bin in the C drive. We declare a structure employee with three members in int - empno, salary and bonus, and define it in the main function as e1.
Now, inside the for loop, we store the value into the file using fwrite(). The first parameter takes the address of e1 and the second parameter takes the size of the structure employee.
Since we're only inserting one instance of e1, the third parameter is 1. And, the last parameter *fptr points to the file we're storing the data. Finally, we close the file.

Let us study a C program that interprets named commands:
struct command
 {
  char *name;
  void (*function) (void);
 };
 struct command commands[] =
 {
   { "quit", quit_command },
  { "help", help_command },
   ...
 };

It is easy to avoid specifying the name of each command twice: once in the string statement and once in the function name. A macro that takes a command name as an argument can make this unnecessary. String expressions can be implemented using string conversions, and function names can be created by concatenating arguments with the "_ command”. Here’s how to do it:

#define COMMAND(NAME)
 {   #NAME,NAME ## _command
 }
struct command commands[] =
 {
  COMMAND (quit),
  COMMAND (help),
 ...
 };


Previous Topic:-->> count vowels in files. || Next topic:-->>file inclusion.