Aula 30 – typedef: Apelidos de Tipo

Como criar nomes semânticos para tipos em C — e por que isso torna o código mais legível e fácil de manter

O que é typedef?

Na aula anterior, cada vez que declarávamos uma variável do tipo aluno precisávamos escrever struct Aluno a;. O typedef elimina essa repetição — e faz muito mais.

typedef cria um apelido (alias) para um tipo já existente. Ele não cria um tipo novo "de verdade" — ele apenas dá um nome alternativo a um tipo, tornando o código mais legível e mais fácil de manter.

Sintaxe básica:

typedef  tipo_original  NomeDoApelido;

Exemplos simples:

typedef int    TIPOCHAVE;   // TIPOCHAVE agora é um apelido para int
typedef float  NOTA;        // NOTA agora é um apelido para float
typedef char   LETRA;       // LETRA agora é um apelido para char

TIPOCHAVE matricula = 1001; // equivale a: int matricula = 1001;
NOTA      media     = 8.5f; // equivale a: float media = 8.5f;
TIPOCHAVE ≠ variável: TIPOCHAVE é um nome de tipo, assim como int é um nome de tipo. Você ainda precisa de um nome de variável: TIPOCHAVE chave; — aqui TIPOCHAVE é o tipo e chave é a variável.

As 3 Grandes Utilidades do typedef

1. Semântica — dar significado ao tipo

Comparar int chave com TIPOCHAVE chave: o segundo comunica intenção. Quem lê o código entende imediatamente que aquele inteiro é uma chave identificadora, não um contador, índice ou qualquer outro int.

Imagine ler 200 linhas de código. Em qual versão fica mais óbvio o papel de cada variável?

int busca(int v[], int n, int chave) — ambíguo
int busca(LISTA *l, int n, TIPOCHAVE chave) — autoexplicativo

2. Manutenção — trocar o tipo em um único lugar

Hoje a chave é um int. Amanhã o sistema precisa de CPF (string de 12 caracteres). Sem typedef: você caça e substitui int em centenas de lugares, arriscando trocar ints que não são chave. Com typedef: uma linha muda:

// Antes
typedef int TIPOCHAVE;

// Depois — só esta linha muda!
typedef char TIPOCHAVE[12];   // agora a chave é um CPF (11 dígitos + '\0')
Atenção ao trocar para string: Quando TIPOCHAVE vira char[12], a comparação == não funciona mais para strings em C — você precisa usar strcmp(). Mas pelo menos o tipo já comunicava que era uma "chave", facilitando encontrar todos os pontos de comparação.

3. Eliminar o struct repetitivo

Sem typedef, toda declaração precisa da palavra struct. Com typedef, o nome já é o tipo completo:

// Sem typedef — precisa repetir 'struct' sempre
struct Aluno { int matricula; float nota; };
struct Aluno a;          // obrigatório: struct Aluno

// Com typedef — nome limpo
typedef struct {
    int   matricula;
    float nota;
} ALUNO;

ALUNO a;                 // sem 'struct', direto ao ponto

typedef com struct: o padrão do projeto

Esta é a forma mais comum e mais usada nos projetos C de estrutura de dados. É exatamente o que aparece no nosso projeto de lista:

#include <stdio.h>
#define MAX 50
#define ERRO -1

// 1. Tipo da chave — um apelido para int
typedef int TIPOCHAVE;

// 2. Um registro — contém pelo menos uma chave
typedef struct {
    TIPOCHAVE chave;
    // outros campos possíveis: char nome[50], float salario, etc.
} REGISTRO;

// 3. A lista — array de registros + contador
typedef struct {
    REGISTRO A[MAX + 1];  // +1 para reservar espaço de sentinela (veremos depois)
    int      nroElem;     // quantos elementos estão realmente na lista
} LISTA;
Por que MAX + 1? Reservamos uma posição extra no array para a técnica de busca com sentinela — um artifício que simplifica o loop de busca. Veremos isso na Aula 34.

Agora, com esses três typedefs, o restante do código fica muito mais limpo:

int main() {
    LISTA   lista;          // não precisa de "struct" na frente
    REGISTRO reg;           // idem
    TIPOCHAVE chave = 42;   // comunica que é uma chave, não um inteiro qualquer
    return 0;
}

Comparação com Java

Java não tem typedef, mas tem conceitos análogos:

Necessidade C (typedef) Java (equivalente)
Dar nome semântico a um tipo primitivo typedef int TIPOCHAVE; Não existe (int é int). Às vezes usa-se uma classe wrapper ou constante.
Criar nome curto para tipo composto typedef struct {...} LISTA; O próprio nome da class Lista já serve.
Capacidade máxima fixa #define MAX 50 static final int MAX = 50;
Tamanho atual / dinâmico Campo int nroElem + manutenção manual ArrayList.size() — automático
Resumo da diferença: Em Java, a própria classe já carrega semântica pelo seu nome (Chave, Registro, Lista). Em C, como não há classes, o typedef é o mecanismo para carregar essa semântica nos tipos primitivos e nas structs.

Exercícios — Aula 30

1. O que o comando typedef int TIPOCHAVE; faz?

2. Qual das declarações abaixo está errada após typedef int TIPOCHAVE;?

3. Qual é a principal vantagem de usar typedef int TIPOCHAVE em vez de int diretamente para as chaves de busca?

4. Após typedef struct { int chave; } REGISTRO;, qual declaração é válida?

5. Por que o array dentro de LISTA é declarado como REGISTRO A[MAX+1] e não REGISTRO A[MAX]?

6. Qual seria a consequência de trocar typedef int TIPOCHAVE por typedef char TIPOCHAVE[12]?

7. Em Java, qual conceito mais se aproxima do papel que typedef struct {...} LISTA desempenha?

8. Analise o código. O que ele imprime?

typedef int METROS;
typedef int KILOS;
METROS distancia = 100;
KILOS  peso = 100;
printf("%d\n", distancia + peso);