#define

The directive #define serves as for replacement of the often used constants, keywords, operators or expressions some identifiers. Identifiers replacing hollerith or numerical constants name the named constants. Identifiers, replacing the fragments of the programs, name macro declarations, thus macro declarations can have arguments. The directive #define has two syntactic forms:
    #define identifier text

#define identifier(list of parameters) text
    
This directive substitutes all subsequent including of identifier by text. Such process is named a macro substitution. Text can be any fragment of the program on C or C++, and also can be absent. In last case all copies of identifier retire from the program.
        #define WIDTH 80

#define LENGTH (WIDTH+10)

These directives will change in text of the program every word WIDTH on a number 80, and every word LENGTH on expression (80+10) together with surrounding him brackets.

The brackets contained in macro declaration allow to avoid misunderstanding related to the order of calculation of triggerable operations. For example, in default of brackets expression t=LENGTH*7 will be regenerate in expression t=80+10*7, but not in expression t=(80+10)*7, as it turns out at presence of brackets, and 780 will ensue, but not 630.
In the second syntactic form in the directive of #define there is a list of formal parameters, that can contain one or a few identifiers divide commas. Formal parameters in text of macro declaration mark positions on that the actual arguments of macrocall must be put. Every formal parameter can appear in text of macro declaration several times.

At a macrocall after an identifier the list of actual arguments the amount of that must coincide with the amount of formal parameters is written down.
#define  MAX(x, y) ((x)>(y))?(x):(y)

// This directive will replace a fragment
t = MAX(i, s[i]);

// on a fragment
t = ((i)>(s[i])?(i):(s[i]);

As well as in a previous example, parentheses, in that are celled formal parameters of macro declaration, allow to avoid the errors of with the wrong order of implementation link transaction, if actual arguments are expressions.
// For example, at presence of brackets fragment
t=MAX(i&j,s[i]||j);

// will be substituted by a fragment
t=((i&j)>(s[i]||j)?(i&j):(s[i]||j);

// and in default of brackets - on a fragment
t=(i&j>s[i]||j)?i&j:s[i]||j;
// in that conditional expression calculates at a completely another order.