Documentação de C
Referência concisa e baseada em exemplos de C. Leia o conceito, veja o código e pratique em uma jornada da Coddy.
Primeiros passos
- O que é CC é uma linguagem pequena, rápida e compilada, de 1972, que ainda roda sistemas operacionais, bancos de dados e praticamente todo dispositivo embarcado. Aqui está o que ela é, onde roda e por que vale a pena aprendê-la em 2026.
- instalar C (GCC)Instale um compilador C funcional em qualquer sistema: MinGW-w64 no Windows, o clang da Apple no macOS e o gcc no Linux - além de como conferir se a instalação deu certo e compilar seu primeiro arquivo.
- Compilar e executarTransforme um arquivo .c em um programa em execução: o comando gcc, o que pré-processamento, compilação e ligação realmente fazem, as flags que valem a pena desde o primeiro dia e como ler os erros quando algo falha.
- sintaxe do CTodo programa em C tem o mesmo esqueleto: includes, uma função main, instruções terminadas em ponto e vírgula e blocos entre chaves. Aqui está o que cada parte faz e as regras que o compilador realmente exige.
- ComentáriosC tem dois estilos de comentário - de uma linha com // e de várias linhas com /* */ - com histórias diferentes e uma armadilha de aninhamento. Veja como usar os dois, além do que vale a pena comentar e do que não vale.
Variáveis e tipos
- VariáveisComo declarar uma variável em C, a diferença entre declaração e inicialização, regras de nomenclatura, declarar várias de uma vez, e por que uma variável não inicializada é o bug de iniciante mais comum.
- Tipos de dadosToda variável em C tem um tipo que fixa seu tamanho e o que ela pode guardar. Aqui estão todos os tipos básicos, seus tamanhos reais, com e sem sinal, sizeof, limits.h e o que acontece no estouro.
- ConstantesTrês formas de dar nome a um valor que nunca muda em C - a palavra-chave const, macros #define e constantes de enum - o que cada uma realmente é e qual usar em cada situação.
- operadoresTodo operador de C que vale a pena conhecer - aritmético, de atribuição, de comparação, lógico e de incremento - mais a armadilha da divisão inteira, como o módulo se comporta com negativos e uma tabela de precedência em que você pode confiar.
- BooleanosC não tinha tipo booleano até o C99. Zero é falso, todo o resto é verdadeiro, comparações resultam em int - e stdbool.h te dá bool, true e false por cima. Mais o bug de = vs == que esse desenho possibilita.
- Conversão de tiposO C converte entre tipos o tempo todo - às vezes porque você pediu com um cast, e mais frequentemente por conta própria. Aqui estão as regras de promoção, a sintaxe do cast explícito e as conversões que perdem dados em silêncio.
Fluxo de controle
- if / elseComo C decide: a instrução if, o else, cadeias de else if, aninhamento e o operador ternário - além da regra de veracidade (0 é falso, todo o resto é verdadeiro) e do bug de `=` vs `==` que quebra condições em silêncio.
- switchComo o switch do C escolhe um ramo a partir de uma lista de constantes - rótulos case, por que o break importa, o fall-through deliberado e o acidental, o default, switch sobre chars e enums, e quando o switch bate uma cadeia de else-if.
- laço forComo repetir código com o laço for do C - o cabeçalho de três partes, contar para cima e para baixo, percorrer arrays com o truque do sizeof, laços aninhados, laços infinitos e os bugs de deslocamento por um e de tipos sem sinal que pegam todo mundo.
- laço whileComo o laço while do C repete até uma condição mudar - a regra da condição primeiro, laços com sentinela, ler entrada até o EOF, while(1) e como converter entre for e while.
- laço do-whileO laço do C que executa o corpo primeiro: como o do-while garante uma passagem antes de testar, por que ele termina com ponto e vírgula, os padrões de menu e de nova tentativa para os quais foi feito, e como se diferencia do while simples.
- break e continuebreak sai de um laço ou de um switch; continue pula para a próxima passagem. Como cada um se comporta em for, while e do-while, como escapar de laços aninhados com uma flag ou goto, e os usos indevidos que deixam laços difíceis de acompanhar.
Funções
- funçõesComo definir e chamar funções em C - o tipo de retorno, os parâmetros, os valores de retorno, funções void, por que a decomposição importa, e um exemplo completo montado com pequenas peças nomeadas.
- parâmetros de funçãoC passa tudo por valor - funções recebem cópias, nunca os originais. O que isso significa na prática, como ponteiros simulam a passagem por referência, por que arrays se comportam de outro jeito, e como retornar vários resultados.
- protótipos de funçãoPor que C precisa ver o formato de uma função antes de você chamá-la - escrever protótipos, corrigir erros de declaração implícita, colocar protótipos em arquivos de cabeçalho, e a diferença real entre f(void) e f().
- recursãoComo uma função em C chama a si mesma - o caso base que a interrompe, fatorial e Fibonacci passo a passo, por que o Fibonacci ingênuo é catastroficamente lento, o que é de fato um estouro de pilha e quando um laço é a resposta melhor.
- escopoOnde uma variável em C é visível e por quanto tempo ela vive - escopo de bloco, parâmetros de função, globais com escopo de arquivo, variáveis locais static que sobrevivem entre chamadas, funções static, sombreamento e por que globais dão problema.
Ponteiros
- ponteirosUm ponteiro é uma variável que guarda um endereço de memória. Esta página constrói a ideia do zero - os operadores & e *, declarar e desreferenciar ponteiros, por que os tipos de ponteiro importam, e a função swap() que mostra por que ponteiros existem.
- aritmética de ponteirosSomar 1 a um ponteiro não soma 1 byte - move para o próximo objeto daquele tipo. Esta página cobre ptr+1, incremento e decremento, diferenças entre ponteiros, comparações, percorrer um array com um ponteiro e a regra do um-além-do-fim.
- ponteiros e arraysEm C um nome de array vira um ponteiro ao seu primeiro elemento em quase todo lugar onde você o usa. Esta página explica esse decaimento, por que arr[i] é literalmente *(arr+i), por que o tamanho do array precisa viajar em separado até as funções, e como um ponteiro para array difere de um array de ponteiros.
- Ponteiros para FunçãoFunções também têm endereços, e um ponteiro para função guarda um deles. Esta página decifra a sintaxe da declaração, mostra como o typedef a torna legível, e chega a callbacks, ao qsort com um comparador personalizado e a tabelas de despacho.
- Ponteiros NULLNULL é o endereço que um ponteiro guarda quando não aponta para nada. Esta página cobre o que NULL realmente é, por que desreferenciá-lo trava o programa, como ele difere de 0 e de um ponteiro não inicializado, e os padrões defensivos que mantêm os bugs de nulo longe do seu código.
Arrays e strings
- ArraysComo declarar e inicializar arrays em C, indexar a partir do zero, calcular o tamanho com sizeof, percorrer os elementos e por que ler além do fim é comportamento indefinido em vez de uma mensagem de erro.
- arrays multidimensionaisComo declarar, inicializar e percorrer arrays 2D em C, o que o layout em ordem de linhas realmente significa na memória, por que passar um array 2D para uma função exige a quantidade de colunas, e um exemplo trabalhado com matrizes.
- StringsO C não tem um tipo string - uma string é um array de char que termina num byte '\0'. Esta página constrói esse modelo mental e depois cobre literais, impressão, percorrimento e por que você não pode copiar uma string com =.
- Funções de stringUm passeio prático pelo <string.h>: medir com strlen, copiar com strcpy e strncpy, juntar com strcat, comparar com strcmp, buscar com strchr e strstr - e como dimensionar buffers para que nenhuma delas estoure.
- Conversão de stringsConvertendo entre texto e números em C: por que o atoi não consegue reportar erro, como usar strtol e strtod corretamente com endptr e errno, transformar números em strings com snprintf, e truques com um único dígito usando '0'.
Memória dinâmica
- Memória dinâmicaPor que o heap existe, como o malloc entrega memória cujo tamanho é decidido em tempo de execução, o idioma p = malloc(n * sizeof *p), verificar NULL, liberar exatamente uma vez e um array dinâmico do começo ao fim.
- calloc e realloccalloc te dá memória zerada e multiplica o tamanho com segurança; realloc aumenta um bloco que você já preencheu. Esta página cobre os dois, o idioma do ponteiro temporário que impede um realloc falho de vazar, e quando calloc ganha de malloc mais memset.
- vazamentos de memóriaO que um vazamento realmente é, as três maneiras pelas quais programas em C os produzem, a disciplina de posse que os previne e como achar o resto com valgrind e -fsanitize=address - terminando com um programa vazando consertado passo a passo.
- Pilha vs HeapOnde seus dados realmente moram: armazenamento automático na pilha, armazenamento dinâmico no heap e o armazenamento estático como terceira região - com o clássico bug do ponteiro pendurado ao devolver uma variável local, e uma regra para escolher.
Structs, unions e enums
- structsComo agrupar valores relacionados num só tipo com uma struct do C - declarar, acessar membros com o operador ponto, inicializadores designados, arrays de structs, aninhamento e a regra de cópia na passagem que surpreende todo mundo.
- Structs e ponteirosComo apontar para uma struct em C - o operador seta, por que (*p).x precisa dos parênteses, passar structs por ponteiro para alterá-las ou evitar cópias, alocar uma struct com malloc e montar um nó de lista encadeada.
- typedefComo o typedef dá um novo nome a um tipo já existente do C - o idioma typedef struct com e sem tag, typedefs para ponteiros de função e arrays, e o único caso em que um typedef atrapalha: esconder um ponteiro.
- unionsComo uma union do C guarda vários tipos nos mesmos bytes - por que o tamanho dela é o do maior membro, por que você precisa ler o membro que escreveu por último, e como uma união etiquetada (enum mais union) a torna segura.
- enumsComo definir um enum em C - numeração automática, valores explícitos, usar enums em um switch para o compilador pegar casos faltantes, converter um enum em string e as convenções de nomes que os mantêm legíveis.
Entrada e saída
- printfComo o printf funciona de verdade em C - o modelo da string de formato, os especificadores do dia a dia, largura e precisão para saída alinhada, como imprimir floats com bom senso, o valor de retorno e por que printf(entrada_do_usuario) é uma falha de segurança.
- scanfComo ler entrada com o scanf em C - por que o & é obrigatório, como os espaços em branco são tratados, o estouro de buffer do %s e a correção com largura, a checagem do valor de retorno, o bug da quebra de linha sobrando e o fgets como alternativa robusta.
- especificadores de formatoTodos os especificadores de formato do C em um só lugar - o que %d, %s, %c, %f, %p e os demais significam, os modificadores de tamanho l, ll, h e z, largura, precisão e flags, e quais deles diferem entre printf e scanf.
- arquivosComo ler e escrever arquivos em C - a tabela de modos do fopen, verificar NULL, escrever com fprintf e fputc, ler com fgets, fscanf e fgetc, o laço canônico linha a linha e quando usar o modo binário.
- argumentos de linha de comandoComo um programa em C lê sua linha de comando - a anatomia de argc e argv, percorrer os argumentos, o que argv[0] guarda, converter números com strtol em vez de atoi, e uma pequena calculadora que junta tudo.
O pré-processador
- pré-processadorO pré-processador edita o texto do seu código antes de o compilador sequer vê-lo - colando cabeçalhos, substituindo macros e ligando ou desligando trechos de código. Aqui está toda a família de diretivas e como olhar a saída dela.
- macrosMacros do tipo objeto e do tipo função com #define - por que cada argumento e o corpo inteiro precisam de parênteses, a armadilha da avaliação múltipla, macros de várias linhas com do-while(0) e quando uma função ou um const é a ferramenta melhor.
- arquivos de cabeçalhoComo dividir um programa em C entre vários arquivos: o que pertence a um .h, o que pertence a um .c, guardas de inclusão que impedem a inclusão dupla, compilar vários arquivos juntos, e compartilhar globais com extern.
- compilação condicionalCompile código diferente para builds diferentes com #ifdef, #ifndef, #if, #elif e #else - chaves de depuração, ramos por plataforma, definir macros pela linha de comando com -D e usar #if 0 para desativar código.
Biblioteca padrão
- funções matemáticasUm passeio pela math.h - sqrt, pow, fabs, floor e ceil, round, fmod, as famílias de trigonometria e logaritmo, INFINITY e NAN - além da flag -lm do linker que causa o clássico erro de undefined reference.
- números aleatóriosComo gerar números aleatórios em C com rand() e RAND_MAX, por que você semeia com srand(time(NULL)) exatamente uma vez, mapear em um intervalo com % e o pequeno viés que isso introduz, doubles aleatórios e sequências reprodutíveis.
- biblioteca-padrãoO que cada cabeçalho padrão oferece - stdio.h, stdlib.h, string.h, math.h, time.h, ctype.h, limits.h, stdbool.h, stdint.h e assert.h - com um exemplo curto e funcional de cada um.
Erros e depuração
- falha-de-segmentaçãoUm segfault significa que seu programa tocou em memória que não lhe pertence. Aqui estão as cinco causas que respondem por quase todos eles, cada uma com um exemplo mínimo e sua correção, além de como achar a linha exata com o gdb e o AddressSanitizer.
- erros comunsOs erros que todo programador C comete pelo menos uma vez - ponto e vírgula faltando, = no lugar de ==, declaração implícita, scanf sem &, comparar strings com ==, divisão inteira, variáveis não inicializadas e deslocamento por um - cada um como sintoma, causa e solução.
- Comportamento indefinidoComportamento indefinido é código sobre o qual a norma do C não impõe requisito nenhum - então qualquer coisa pode acontecer, inclusive o otimizador apagar suas verificações. Aqui está o que o causa, por que "funciona na minha máquina" não prova nada, e as flags que o pegam.