O Preprocessor
Toda linha que começa com # é tratada pelo preprocessor, um passo separado que roda antes do compilador real ver seu código. #include <stdio.h> literalmente cola o conteúdo daquele header file no lugar; #define SQUARE(x) ((x) * (x)) define uma macro que é substituída textualmente em todo lugar onde é usada, com seu argumento substituído — SQUARE(5) se torna ((5) * (5)) antes mesmo da compilação começar.
#include <stdio.h>
#define SQUARE(x) ((x) * (x))
#define MAX_USERS 100
int main() {
printf("%d\n", SQUARE(5));
printf("%d\n", MAX_USERS);
return 0;
}25 100
Macros não são functions — elas não têm verificação de tipos nem parâmetros reais, apenas substituição de texto — que é exatamente por que SQUARE(x) é envolvido em parênteses extras: sem eles, SQUARE(1 + 2) expandiria para 1 + 2 * 1 + 2, não (1 + 2) * (1 + 2). Nenhuma outra linguagem deste site tem algo assim: é genuinamente uma camada textual separada por baixo da linguagem C real.
A seguir: operators bitwise — manipular bits individuais diretamente.
Practice exercise
Defina uma macro SQUARE(x) que se expanda para ((x) * (x)), depois imprima SQUARE(9).