# Programar em C/Pré-processador
## O pré-processador

O pré-processador C é um programa que examina o programa fonte escrito em C e executa certas modificações nele, baseado nas diretivas de compilação (ou diretivas do pré-processador). As diretivas de compilação são comandos que não são compilados, sendo dirigidos ao pré-processador, executado pelo compilador antes da execução do processo de compilação propriamente dito.
Portanto, o pré-processador modifica o programa fonte, que ainda não estaria pronto para ser entregue ao compilador. Todas as diretivas de compilação são iniciadas pelo caractere # (sharp). As diretivas podem ser colocadas em qualquer parte do programa, mas não podem ser colocadas na mesma linha que outra diretiva ou instrução.
As principais diretivas de compilação são:
* #include
* #define
* #undef
* #ifdef
* #ifndef
* #if
* #else
* #elif
* #endif

## Diretivas de compilação
### #include

A diretiva #include diz ao pré-processador para incluir naquele ponto um arquivo especificado. Sua sintaxe é:
ou
A diferença entre se usar "" e <> é somente a ordem de procura nos diretórios pelo arquivo especificado. Se você quiser informar o nome do arquivo com o caminho completo, ou se o arquivo estiver no diretório de trabalho, use "arquivo". Se o arquivo estiver nos caminhos de procura pré-especificados do compilador, isto é, se ele for um arquivo do próprio sistema (como é o caso de arquivos como stdio.h, string.h, etc...), use <arquivo>.

### #define

A diretiva #define tem duas utilidades. Uma delas é apenas definir um símbolo que pode ser testado mais tarde. Outra é definir uma constante ou ainda uma macro com parâmetros. As três maneiras de usar a diretiva são:
* Toda vez que o pré-processador encontrar nome_da_constante no código a ser compilado, ele deve substituí-lo por valor_da_constante.
* Toda vez que o pré-processador encontrar nome_da_macro(parâmetros), ele deve substituir por expressão_de_substituição, também substituindo os parâmetros encontrados na expressão de substituição; funciona mais ou menos como uma função. Veja o exemplo para entender melhor.
Exemplo 1:
Exemplo 2:
Aqui, a linha de código: x = max(i, j); será substituída pela linha: x = ((i) > (j) ? (i) : (j));. Ou seja, atribuiremos a x o maior valor entre i ou j.
Quando você utiliza a diretiva #define, nunca deve haver espaços em branco no identificador (o nome da macro). Por exemplo, a macro #define PRINT (i) printf(" %d \n", i) não funcionará corretamente porque existe um espaço em branco entre PRINT e (i).

### #undef

A diretiva #undef tem a seguinte forma geral:
Ela faz com que a macro que a segue seja apagada da tabela interna que guarda as macros. O compilador passa a partir deste ponto a não conhecer mais esta macro.

### #ifdef e #ifndef

O pré-processador também tem estruturas condicionais. No entanto, como as diretivas são processadas antes de tudo, só podemos usar como condições expressões que envolvam constantes e símbolos do pré-processador. A estrutura ifdef é a mais simples delas:
O código entre as duas diretivas só será compilado se o símbolo (ou constante) nome_do_símbolo já tiver sido definido. Há também a estrutura ifndef, que executa o código se o símbolo não tiver sido definido.
Lembre que o símbolo deve ter sido definido através da diretiva #define.

### #if

A diretiva #if tem a seguinte forma geral:
A sequência de declarações será compilada apenas se a expressão fornecida for verdadeira. É muito importante ressaltar que a expressão fornecida não pode conter nenhuma variável, apenas valores constantes e símbolos do pré-processador.

### #else

A diretiva #else funciona como na estrutura de bloco if (condição) {...} else {...}:
Um exemplo:

### #elif

A diretiva #elif serve para implementar uma estrutura do tipo if (condição) {...} else if (condição) {...}. Sua forma geral é:
Podemos também misturar diretivas #elif com #else; obviamente, só devemos usar uma diretiva #else e ela deve ser a última (antes de #endif).

## Usos comuns das diretivas

Um uso muito comum das diretivas de compilação é em arquivos-cabeçalho, que só precisam/devem ser incluídos uma vez. Muitas vezes incluímos indiretamente um arquivo várias vezes, pois muitos cabeçalhos dependem de outros cabeçalhos. Para evitar problemas, costuma-se envolver o arquivo inteiro com um bloco condicional que só será compilado se o arquivo já não tiver incluído. Para isso usamos um símbolo baseado no nome do arquivo. Por exemplo, se nosso arquivo se chama "cabecalho.h", é comum usar um símbolo com o nome CABECALHO_H:
Se o arquivo ainda não tiver sido incluído, ao chegar na primeira linha do arquivo, o pré-processador não encontrará o símbolo CABECALHO_H, e continuará a ler o arquivo, o que lhe fará definir o símbolo. Se tentarmos incluir novamente o arquivo, o pré-processador pulará todo o conteúdo pois o símbolo já foi definido.

## Concatenação

O pré-processador C oferece duas possibilidades para manipular uma cadeia de caracteres . A primeira é usando o operador # que permite substituir a grafia de um parâmetro .
A segunda é usando o operador ## que serve para concatenar vários parâmetros . Ex: ban##ana é igual a banana .