C é uma linguagem de programação compilada e de propósito geral criada por Dennis Ritchie no Bell Labs em 1972 para escrever o sistema operacional Unix. Ela sobreviveu a quase tudo da sua época, e a razão é simples: C fica uma camada fininha acima da máquina. Ela dá acesso direto à memória e às capacidades reais da CPU, e ainda assim se lê como algo que uma pessoa escreveu.
Meio século depois, ela continua sendo a linguagem em que as outras linguagens são construídas.
Um programa C completo
Aqui está a forma da linguagem inteira em seis linhas. Aperte Executar.
#include <stdio.h> traz as declarações padrão de entrada/saída, para que printf seja conhecido. main é onde todo programa C começa. printf escreve texto, \n é uma quebra de linha, e return 0 diz ao sistema operacional que o programa terminou com sucesso. Esse é um programa completo e compilável - não há classe para envolvê-lo nem framework por baixo.
O que torna C diferente
A maioria das linguagens modernas esconde a máquina de você. C deliberadamente não esconde.
- É compilada para código nativo. Um programa C vira instruções de máquina para uma CPU e roda direto, sem interpretador e sem máquina virtual no meio.
- Você gerencia a memória. Não há coletor de lixo. Você pede memória e você a devolve. Isso dá mais trabalho, e também é por isso que programas C usam tão pouca memória e têm um tempo tão previsível.
- É pequena. C tem cerca de 32 palavras-chave. Você consegue guardar a linguagem inteira na cabeça, o que não vale para C++, Java ou Python.
- Quase não há runtime. Um programa C pode rodar em um microcontrolador com alguns kilobytes de RAM e nenhum sistema operacional.
A troca é honestidade em vez de segurança. C vai deixar você ler além do fim de um array ou usar memória que já liberou, e não vai te impedir. Esses erros têm nome - falhas de segmentação, vazamentos de memória, comportamento indefinido - e aprender C é, em grande parte, aprender a evitá-los.
Onde C roda de verdade
C não é uma curiosidade histórica. Ela está rodando no aparelho em que você lê isto, várias vezes.
- Sistemas operacionais. O kernel do Linux tem cerca de 30 milhões de linhas de C. Grandes partes do Windows e do kernel da Apple também são C.
- Sistemas embarcados. Microcontroladores em carros, termostatos, equipamentos médicos, roteadores e máquinas de lavar são programados majoritariamente em C. Quando o chip inteiro tem 32 KB de memória, C costuma ser a única opção realista.
- Bancos de dados. SQLite, PostgreSQL, MySQL e Redis são programas em C.
- Runtimes de linguagens. O CPython, o interpretador de referência do Python, é escrito em C. O MRI do Ruby, a engine Zend do PHP e o núcleo do Lua também. Quando o Python é "lento demais", a solução geralmente é uma extensão em C.
- Ferramentas e bibliotecas. Git, curl, FFmpeg, OpenSSL, zlib, SQLite de novo - a camada de infraestrutura da computação é C.
É também por isso que a interface binária de aplicação (ABI) do C importa: quase toda linguagem consegue chamar uma função C. Python, Rust, Go, Java e JavaScript todas têm um jeito de alcançar bibliotecas C. C é a língua franca entre linguagens.
Por que aprender C
Há duas respostas honestas, e elas apontam para pessoas diferentes.
Se você quer trabalhar com sistemas - kernels, drivers, firmware embarcado, bancos de dados, motores de jogos - C é a linguagem de trabalho dessa área, e a maioria das vagas nesses campos a cita diretamente (muitas vezes ao lado de C++ ou Rust). É difícil contribuir com o Linux, com o PostgreSQL ou com o código de um microcontrolador sem ler C com desenvoltura.
Se você quer ser melhor na linguagem que já usa, C ensina o que existe por baixo. Depois de C você sabe por que o índice de um array começa em zero, o que uma string realmente é, por que passar um objeto grande por valor é caro, o que são a pilha e o heap, e para onde um ponteiro nulo de fato aponta. Esses conceitos aparecem em todas as linguagens; C é onde eles ficam visíveis em vez de escondidos.
Esse programa tem três linhas de C e é também uma demonstração completa do que é uma variável: uma caixa com nome em um endereço. Na maioria das linguagens você nem consegue fazer essa pergunta.
C e C++
C++ começou em 1979 como "C com classes" e cresceu até virar uma das maiores linguagens que existem: classes, templates, exceções, sobrecarga de operadores, a STL, ponteiros inteligentes e uma biblioteca padrão que faz a especificação inteira do C parecer pequena.
A relação na prática:
- C++ manteve a sintaxe de C, então
if,for,while, operadores, ponteiros e arrays se parecem nas duas. - A maior parte do C bem escrito compila como C++, com algumas exceções (C++ exige converter o resultado de
malloc, por exemplo). - Código C++ quase nunca é C válido.
Se você pretende aprender as duas, aprender C primeiro é uma vantagem real: C++ se apoia diretamente no modelo de memória de C, e as partes de C++ que mais confundem as pessoas - ponteiros, referências, semântica de cópia, destrutores - são todas respostas a problemas que C mostra abertamente.
C não é um subconjunto de C++ em nenhum sentido oficial, no entanto. São padrões separados evoluindo separadamente, e o C moderno tem recursos que C++ não tem (inicializadores designados chegaram no C99, ponteiros restrict e arrays de tamanho variável).
Qual C: as versões do padrão
C é padronizada, e a versão importa quando você lê código antigo.
| Padrão | Ano | Vale conhecer por |
|---|---|---|
| C89 / C90 | 1989 | A base antiga. Variáveis declaradas só no topo de um bloco. |
| C99 | 1999 | Comentários //, declarar variáveis em qualquer lugar, bool via stdbool.h, long long |
| C11 | 2011 | Threads, atômicos, funções de biblioteca mais seguras |
| C17 | 2018 | Uma versão de correção de bugs do C11 - o padrão comum hoje |
| C23 | 2024 | true/false/bool como palavras-chave, nullptr, literais binários |
Esta documentação tem como alvo o C17 e destaca recursos do C99+ onde eles importam. Os compiladores já usam algo moderno por padrão, mas você pode ser explícito:
gcc -std=c17 -Wall -Wextra hello.c -o hello
O que C não tem
Parte de entender C é saber o que falta, porque quase toda pergunta do tipo "como eu faço..." tem uma resposta diferente aqui e em uma linguagem moderna.
- Não há strings. Uma string em C é um array de
charterminado por um byte zero. Concatenar duas significa chamar uma função e se preocupar se o destino é grande o bastante. - Não há coleções. Sem listas, mapas ou conjuntos. Você tem arrays fixos e ponteiros; uma tabela hash é algo que você escreve ou para o que liga uma biblioteca.
- Não há exceções. Funções reportam falha devolvendo um valor especial -
-1,NULLou um código de status - e espera-se que quem chamou verifique. - Não há genéricos nem sobrecarga. Um nome de função significa uma função. É por isso que a biblioteca padrão tem
abs,labsefabspara três tipos diferentes. - Não há namespaces nem módulos. Toda função não
staticcompartilha um namespace global, que é por que bibliotecas C prefixam tudo (sqlite3_open,png_read_info). - Não há coletor de lixo. Todo
mallocprecisa de umfreecorrespondente, e esquecer é um vazamento de memória.
Nada disso é um descuido. Algumas coisas são maquinaria de tempo de execução que C se recusa a carregar (um coletor de lixo, o desenrolamento de exceções, strings que crescem), e isso explica boa parte de por que ela cabe em um chip com 2 KB de RAM; outras, como espaços de nomes e genéricos, são recursos de linguagem que simplesmente vieram depois do projeto de C e ficaram de fora para mantê-la pequena.
O buffer tem 32 bytes porque você decidiu que era suficiente. C não vai verificar, e essa decisão é todo o caráter da linguagem em uma linha.
C é difícil?
C é pequena, mas implacável. Não há muita sintaxe para memorizar - dá para ler a linguagem inteira em uma semana. O que leva tempo é a disciplina: acompanhar quem é dono de qual pedaço de memória, lembrar que uma string é só bytes terminados em zero, verificar se um ponteiro não é nulo antes de segui-lo.
A maior parte da dificuldade de C não está nos conceitos, e sim na falta de guarda-corpos: o compilador não vai te salvar de uma escrita fora dos limites nem de um ponteiro pendurado, então você aprende a ser preciso. (Os ponteiros em si exigem esforço de verdade na primeira vez - isso é normal, e o capítulo de ponteiros os apresenta com calma.) Essa precisão é uma habilidade que se transfere para todas as linguagens que você usar depois.
Perguntas frequentes
O que é a linguagem de programação C?
C é uma linguagem de programação compilada e de propósito geral criada por Dennis Ritchie no Bell Labs em 1972. Ela dá controle direto sobre a memória e se aproxima bastante do que a CPU realmente faz, que é por que sistemas operacionais, drivers de dispositivo e bancos de dados ainda são escritos nela.
Para que C é usada hoje?
Kernels de sistemas operacionais (Linux, partes do Windows e do macOS), firmware embarcado em carros, eletrodomésticos e microcontroladores, bancos de dados como SQLite e PostgreSQL, runtimes de linguagens como CPython e Redis, e bibliotecas críticas de desempenho que outras linguagens chamam.
Ainda vale a pena aprender C em 2026?
Sim, por dois motivos. Ela continua sendo a linguagem do trabalho de sistemas e de embarcados, que é um campo grande e bem pago. E ela ensina como a memória, os ponteiros e a pilha funcionam de verdade - conhecimento que te torna melhor em todas as outras linguagens, porque a maioria delas é implementada em C.
Qual é a diferença entre C e C++?
C++ começou como "C com classes" e manteve a maior parte da sintaxe de C ao mesmo tempo em que acrescentou programação orientada a objetos, templates, a biblioteca padrão e muito mais. C é bem menor: sem classes, sem exceções, sem genéricos. A maior parte do código C válido compila como C++, mas não o contrário.