Visão geral da linguagem C
C (ANSI C99 / C11) — linguagem de sistemas | tempo de execução mínimo | memória manual | controle máximo
Paradigma
Imperativo, processual. Tipagem estática com sistema de tipo fraco (conversões implícitas, void*). Compilação via pré-processador → compilador → montador → vinculador. Compilação de uma passagem, baseada em unidade de tradução.
Tipos
| Categoria | Tipos | Tamanho (típico) |
|---|---|---|
| personagem | char |
1 byte |
| Assinado | signed char short int long long long |
1, 2, 4, 8, 8 bytes |
| Int não assinado | unsigned char unsigned short unsigned int unsigned long unsigned long long |
1, 2, 4, 8, 8 bytes |
| Flutuar | float double long double |
4, 8, 8-16 bytes |
| Bool (C99) | _Bool / bool (através de <stdbool.h>) |
1 byte |
| Vazio | void |
0 (incompleto) |
| Ponteiro | T* |
8 bytes (64 bits) |
| Matriz | T[N] T[] |
N * tamanho de (T) |
| Estrutura | struct Name { ... } |
Soma dos campos + preenchimento |
| União | union Name { ... } |
Máximo de campos |
| Enum | enum Name { ... } |
tamanho de (int) |
| Ponteiro de função | T (*)(args) |
8 bytes |
Modificadores de tipo
const volatile restrict (C99) inline (C99)
Especificadores de classe de armazenamento
auto register static extern _Thread_local (C11)
Declarações
| Construir | Sintaxe | Notas |
|---|---|---|
| Função | T name(params) { body } |
|
| Protótipo | T name(params); |
Declaração sem corpo |
| Variável | T x = expr; |
|
| Múltiplo | T x, y, z; |
|
| Constante | const T x = expr; |
|
| Constante de enumeração | enum { VAL = expr }; |
|
| Tipo de definição | typedef T Alias; |
|
| Estrutura | struct Name { T field; }; |
|
| União | union Name { T field; }; |
|
| Externo | extern T name; |
Definido em outra TU |
| Estático | static T name; |
Ligação interna |
Fluxo de controle
| Construir | Sintaxe | Notas |
|---|---|---|
| Se | if (cond) { ... } else { ... } |
Declaração, não expressão |
| Enquanto | while (cond) { ... } |
|
| Faça enquanto | do { ... } while (cond); |
|
| Para | for (init; cond; incr) { ... } |
|
| Mudar | switch (expr) { case N: ... break; } |
Fall-through por padrão |
| Pausa | break; |
Sair loop/switch |
| Continuar | continue; |
Pular para a próxima iteração |
| Ir para | goto label; |
Apenas dentro da função |
| Retorno | return expr; |
Operadores (precedência, do maior para o menor)
| Precedência | Operadores | Associação |
|---|---|---|
| 1 | () [] . -> ++ -- (postfixo) |
Esquerda |
| 2 | ++ -- (prefixo) + - ! ~ * & sizeof _Alignof |
Certo |
| 3 | (type) (elenco) |
Certo |
| 4 | * / % |
Esquerda |
| 5 | + - |
Esquerda |
| 6 | << >> |
Esquerda |
| 7 | < > <= >= |
Esquerda |
| 8 | == != |
Esquerda |
| 9 | & |
Esquerda |
| 10 | ^ |
Esquerda |
| 11 | | |
Esquerda |
| 12 | && |
Esquerda |
| 13 | || |
Esquerda |
| 14 | ? : (ternário) |
Certo |
| 15 | = += -= *= /= %= &= ^= |= <<= >>= |
Certo |
| 16 | , (operador vírgula) |
Esquerda |
Pré-processador
| Diretiva | Objetivo |
|---|---|
#include "file" / <file> |
Inclusão textual |
#define MACRO body |
Macro semelhante a um objeto |
#define MACRO(args) body |
Macro semelhante a uma função |
#undef MACRO |
Remover macro |
#if expr / #ifdef MACRO / #ifndef MACRO |
Compilação condicional |
#elif expr / #else / #endif |
Outras filiais |
#error "message" |
Erro em tempo de compilação |
#pragma |
Definido pela implementação |
#line N "file" |
Controle de linha |
## (colagem de token) |
Concatenar tokens |
# (stringificar) |
Converter em string literal |
Macros predefinidas (C99)
__LINE__ __FILE__ __DATE__ __TIME__ __STDC__ __STDC_VERSION__ __func__
Memória
| Operação | Sintaxe | Cabeçalho |
|---|---|---|
| Alocar | malloc(n) |
<stdlib.h> |
| Alocação alinhada (C11) | aligned_alloc(a, n) |
<stdlib.h> |
| Calloc | calloc(n, size) |
<stdlib.h> |
| Reallocar | realloc(p, n) |
<stdlib.h> |
| Grátis | free(p) |
<stdlib.h> |
| Copiar | memcpy(dst, src, n) |
<string.h> |
| Mover (seguro sobreposição) | memmove(dst, src, n) |
<string.h> |
| Definir | memset(p, c, n) |
<string.h> |
| Comparar | memcmp(a, b, n) |
<string.h> |
| Pilha | alloca(n) (não padrão) |
<alloca.h> |
Biblioteca Padrão (selecionada)
<stdio.h>
printf scanf fopen fclose fread fwrite fprintf sprintf fgets fputs feof ferror remove rename tmpfile
<stdlib.h>
atoi atof strtol strtod rand srand abs qsort bsearch system getenv exit abort atexit
<string.h>
strlen strcpy strncpy strcat strncat strcmp strncmp strchr strrchr strstr strtok memset memcpy memmove memcmp
<math.h>
sin cos tan asin acos atan atan2 sqrt pow exp log log10 fabs ceil floor fmod fma
<time.h>
time clock difftime mktime strftime localtime gmtime
<assert.h>
assert(expr)
<stdint.h> (C99)
int8_t int16_t int32_t int64_t uint8_t uint16_t uint32_t uint64_t intptr_t uintptr_t size_t
<stdbool.h> (C99)
bool true false
Compilação
| Passo | Comando | Saída |
|---|---|---|
| Pré-processar | cpp file.c > file.i |
Fonte expandida |
| Compilar | cc -S file.c |
Montagem (file.s) |
| Montar | cc -c file.c |
Objeto (file.o) |
| Ligação | cc file.o -o prog |
Executável (prog) |
| Tudo-em-um | cc file.c -o prog |
Executável direto |
Sinalizadores Comuns
-O0 -O1 -O2 -O3 -Os -g -Wall -Wextra -Wpedantic -std=c99 -std=c11 -DNAME=val -Ipath -Lpath -llib
Conjunto de ferramentas
GCC (GNU), Clang/LLVM, MSVC (Windows), TinyCC, CompCert
Duração do armazenamento
| Duração | Alocação | Vitalício |
|---|---|---|
| Automático | Pilha | Escopo |
| Estático | Segmento de dados | Vida útil do programa |
| Thread-local (C11) | TLS | Vida útil do thread |
| Alocado | Pilha (malloc/free) |
Manuais |
Ligação
| Palavra-chave | Ligação | Visibilidade |
|---|---|---|
| (nenhum, escopo do arquivo) | Externo | Programa completo |
static (escopo do arquivo) |
Interno | Unidade de tradução atual |
extern |
Externo | Programa completo |
static inline (C99) |
Interno | TU atual (sem fora de linha) |
Comportamento indefinido (armadilhas selecionadas)
- Estouro de buffer (índice de array fora dos limites)
- Use-após-livre / duplamente livre
- Estouro de número inteiro assinado
- Desreferenciando ponteiro NULL
- Divisão por zero
- Violação estrita de alias
- Endereço de retorno da variável automática
- Modificando literal de string
- Corrida de dados (acesso simultâneo não sincronizado)
- Mudar por >= largura do tipo
C99 vs C11 vs C17 vs C23
| Padrão | Principais adições |
|---|---|
| C89/ANSI C | Padrão original |
| Capítulo 99 | // comentários, stdint.h, bool, restrict, inline, macros variadas, inicializadores designados, literais compostos, for-declarações de escopo |
| C11 | _Generic, _Static_assert, _Alignas, _Alignof, _Atomic, _Thread_local, anônimo structs/unions, noreturn, interfaces com verificação de limites (Anexo K) |
| Capítulo 17 | Lançamento de correção de bug (sem novos recursos) |
| C23 (rascunho) | typeof, nullptr, #embed, bool como palavra-chave, static_assert sem _, constexpr, auto para inferência de tipo |
Idiomas C comuns
Ponteiro opaco (encapsulamento)
// header
typedef struct Handle Handle;
Handle* handle_create(void);
void handle_destroy(Handle*);
// implementation
struct Handle { int fd; };
Retorno de chamada (ponteiro de função)
void sort(int* arr, int n, int (*cmp)(int, int));
Orientado a objetos (vtable manual)
struct Vtable { void (*draw)(void*); };
struct Shape { struct Vtable* vtable; };
Genérico (void* + ponteiro de função)
void qsort(void* base, size_t n, size_t size,
int (*cmp)(const void*, const void*));