Constantes
Esta aula aborda as diferentes formas de definir constantes em C: a palavra-chave const, a diretiva #define, enumerações (enum) e literais. Você aprenderá quando e como usar cada uma, com exemplos práticos e boas práticas.
Constantes são valores que não mudam durante a execução do programa. Em C, existem várias maneiras de defini-las, cada uma com suas vantagens e contextos de uso. Nesta aula, exploraremos as principais formas: a palavra-chave const, a diretiva de pré-processador #define, enumerações (enum) e literais. Compreender essas diferenças é essencial para escrever código claro, seguro e de fácil manutenção.
Além disso, veremos como constantes podem tornar o código mais legível e evitar erros, especialmente em programas maiores. Vamos mergulhar em cada uma delas.
const
A palavra-chave const é usada para declarar variáveis cujo valor não pode ser alterado após a inicialização. É uma forma segura e com verificação de tipo, pois o compilador garante que a variável não seja modificada. Diferente de #define, const respeita escopo e tipos.
Exemplo:
const int MAX = 100;
const float PI = 3.14159;
const char MENSAGEM[] = "Olá, mundo!";Note que variáveis const devem ser inicializadas no momento da declaração. Em C, const não cria uma constante de tempo de compilação (não pode ser usada em tamanhos de array estático, por exemplo), mas ainda assim é útil para valores imutáveis.
#define
A diretiva #define é uma instrução de pré-processador que substitui um identificador por um texto antes da compilação. É frequentemente usada para definir constantes simbólicas, macros e até mesmo pequenas funções. Por não ter verificação de tipo, deve ser usada com cuidado.
Exemplo:
#define MAX 100
#define PI 3.14159
#define AREA_CIRCULO(r) (PI * (r) * (r))O pré-processador substitui todas as ocorrências de MAX por 100 antes da compilação. Diferente de const, #define não aloca memória e pode ser usado em contextos que exigem constantes de tempo de compilação, como tamanhos de arrays estáticos.
Boas práticas: use letras maiúsculas para constantes definidas com #define e parênteses em macros para evitar problemas de precedência.
Enumerações (enum)
Enumerações são tipos definidos pelo usuário que consistem em um conjunto de constantes inteiras nomeadas. São ideais para representar um conjunto de opções ou estados, tornando o código mais legível e menos propenso a erros.
Exemplo:
enum Dias {SEG, TER, QUA, QUI, SEX, SAB, DOM};
enum Dias hoje = SEG;
enum Estado {LIGADO = 1, DESLIGADO = 0, INDEFINIDO = -1};Por padrão, os valores começam em 0 e incrementam de 1 em 1, mas podem ser explicitamente atribuídos. Enumerações são úteis em switches e para evitar números mágicos.
Literais
Literais são valores constantes escritos diretamente no código. Eles representam valores fixos de tipos básicos como inteiros, ponto flutuante, caracteres e strings. Exemplos:
42 // literal inteiro (int)
3.14 // literal double
'a' // literal caractere (char)
"Hello" // literal string (array de char)
0xFF // literal hexadecimal
0777 // literal octal
1e-3 // literal científicoLiterais são imutáveis por natureza. Em C, literais string são armazenados em área somente leitura, e tentar modificá-los resulta em comportamento indefinido.
Boas práticas e observações finais
Preferir const em vez de #define para constantes tipadas, a menos que precise de uma constante de tempo de compilação. Use enumerações para conjuntos de valores relacionados. Evite números mágicos; sempre nomeie constantes para melhorar a legibilidade. Lembre-se de que #define não tem escopo, enquanto const e enum respeitam escopo de bloco.
Referências
- cppreference: const (C)
- cppreference: #define
- cppreference: enum
- cppreference: Literais (C)
- GNU C Manual: Constants
Exercícios
Declare uma constante
constchamadaTAXA_JUROScom valor 0.05 e uma variáveldoublechamadasaldoinicializada com 1000.0. Calcule e imprima o saldo após aplicar a taxa (saldo * (1 + TAXA_JUROS)).✓ Resposta:#include <stdio.h> int main() { const double TAXA_JUROS = 0.05; double saldo = 1000.0; double novo_saldo = saldo * (1 + TAXA_JUROS); printf("Novo saldo: %.2f\n", novo_saldo); return 0; }Usando
#define, crie uma macro que calcula o quadrado de um número. Depois, use-a para imprimir o quadrado de 7.✓ Resposta:#include <stdio.h> #define QUADRADO(x) ((x) * (x)) int main() { printf("%d\n", QUADRADO(7)); return 0; }Defina uma enumeração
enum Mesescom os meses do ano (JAN a DEZ). Atribua a JAN o valor 1. Imprima o valor de DEZ.✓ Resposta:#include <stdio.h> enum Meses { JAN = 1, FEV, MAR, ABR, MAI, JUN, JUL, AGO, SET, OUT, NOV, DEZ }; int main() { printf("%d\n", DEZ); return 0; }Escreva um programa que use literais para calcular a área de um círculo de raio 5. Use o literal
3.14159para PI.✓ Resposta:#include <stdio.h> int main() { double raio = 5; double area = 3.14159 * raio * raio; printf("Área: %.2f\n", area); return 0; }Explique por que usar
const inté preferível a#definepara definir uma constante inteira em um programa com múltiplos arquivos. Dê um exemplo de código.✓ Resposta:const inttem escopo e tipo, prevenindo erros de substituição inesperada e permitindo que o compilador verifique tipos. Já#defineé uma substituição textual sem escopo, podendo causar conflitos. Em múltiplos arquivos,constpode ser usada comexternpara compartilhar, enquanto#defineprecisa ser redefinida ou incluída em cada arquivo. Exemplo:// arquivo config.h extern const int MAX_USUARIOS; // arquivo config.c const int MAX_USUARIOS = 100; // main.c #include "config.h" int main() { int arr[MAX_USUARIOS]; // erro: não é constante de tempo de compilação // melhor usar #define para tamanho de array estático }