Variáveis globais em C, escopo, tempo de vida e a palavra-chave static explicados.
📖 O que aprender nesta página
✅ Essencial que você precisa saber
Declarada fora de qualquer função → global
Visível e alterável por qualquer função
Uma variável local sombreia uma global de mesmo nome
⭐ Leia se tiver tempo
static esconde de outros arquivos
extern referencia de outros arquivos
Evite abusar de variáveis globais
Escopo — onde uma variável está visível
A região em que uma variável pode ser referenciada — seu escopo — é determinada pelo local onde você a declara.
intmain(void) {
int a = 10; // valid inside mainif (a > 0) {
int b = 20; // valid only inside this blockprintf("%d\n", a+b); // OK
}
// printf("%d\n", b); ← error! b is out of scope
}
Variável local
Válida somente dentro da função ou bloco. Destruída ao sair.
Variável global
Declarada fora de qualquer função. Acessível de qualquer lugar.
Variável static
Uma variável local que mantém seu valor entre as chamadas.
Tempo de vida da variável — quando nasce e quando morre
Escopo diz onde uma variável está visível. Tempo de vida diz quando ela é alocada em memória e quando é liberada.
Três tipos de tempo de vida
Tipo
Onde é declarada
Criada quando
Destruída quando
auto (local)
dentro de uma função/bloco
quando o bloco é entrado
quando o bloco é deixado
global
fora de qualquer função
início do programa
fim do programa
static
dentro de uma função (com static)
início do programa
fim do programa
voidexample(void) {
int a = 1; // auto: created per call, gone on exitstaticint b = 1; // static: created once, value persists
a++; b++;
printf("a=%d b=%d\n", a, b);
}
intmain(void) {
example(); // a=2 b=2example(); // a=2 b=3 ← a resets, b persistsexample(); // a=2 b=4
}
Visualize o tempo de vida
Clique no botão para ver como cada variável muda à medida que example() é chamada três vezes.
Passo 0 / 9
Estado da chamada
Variáveis na memória
Saída
Variáveis globais — compartilhadas entre todas as funções
#include<stdio.h>int counter = 0; // global variable (outside main, etc.)voidincrement(void) {
counter++; // usable without any argument
}
intmain(void) {
increment();
increment();
increment();
printf("%d\n", counter); // → 3
}
Não abuse delas: variáveis globais são convenientes, mas é difícil rastrear onde são modificadas, então tendem a abrir espaço para bugs. Use com moderação.
Variáveis static — persistem entre as chamadas
Uma variável local comum é destruída assim que a função retorna, mas adicionar static faz com que ela viva até o fim do programa.
voidcount(void) {
staticint n = 0; // initialized to 0 only once
n++;
printf("Call count: %d\n", n);
}
intmain(void) {
count(); // → 1count(); // → 2count(); // → 3
}
Quando usar: quando você quer contar quantas vezes uma função foi chamada ou lembrar um resultado anterior — especialmente quando precisa manter estado sem os riscos de uma variável global completa.
Layout de memória — onde as variáveis realmente vivem?
Variáveis locais, globais e static são armazenadas em regiões de memória diferentes. Essa é a razão real para seus tempos de vida serem diferentes.
Mapa de memória de um programa em C
Quando um programa em C é executado, a memória é dividida em cinco regiões:
Endereço alto ↑
📚 Pilha (Stack)
Variáveis locais, argumentos de função e endereços de retorno. Alocadas e liberadas automaticamente a cada chamada de função.
↓ cresce para baixo ↓
(espaço livre)
↑ cresce para cima ↑
🧱 Heap
Alocada dinamicamente via malloc / free. Gerenciada explicitamente pelo programador.
🌐 BSS (Dados não inicializados)
Variáveis globais e static não inicializadas. Automaticamente zeradas no início do programa.
💾 Data (Inicializadas)
Variáveis globais e static inicializadas. Vivem pelo programa inteiro.
📜 Text (Código)
Código de máquina e literais de string. Somente leitura.
Endereço baixo ↓
Código mapeado nas regiões
#include<stdio.h>#include<stdlib.h>int g_init = 100; // 💾 Data segment (initialized)int g_uninit; // 🌐 BSS (uninitialized → auto-zeroed)voidfunc(void) {
int local = 5; // 📚 Stack (new copy per call)staticint s = 0; // 💾 Data segment (created once)int *heap = malloc(sizeof(int)); // 🧱 Heap
*heap = 42;
free(heap);
}
intmain(void) {
func();
return0;
}
Tipos de variáveis e suas regiões de memória
Tipo de variável
Declarada em
Região de memória
Criada
Valor inicial
Local (auto)
Dentro da função
📚 Pilha
Na chamada da função
Indefinido (lixo)
Local (static)
Dentro da função + static
💾 Data / BSS
No início do programa
0 ou valor especificado
Global (inicializada)
Fora de qualquer função
💾 Data
No início do programa
Valor especificado
Global (não inicializada)
Fora de qualquer função
🌐 BSS
No início do programa
0 (automático)
Alocada com malloc
Dinâmica dentro da função
🧱 Heap
Na chamada de malloc
Indefinido (calloc: 0)
Literal de string
Código-fonte "..."
📜 Text
No início do programa
Somente leitura
Chamadas de função e a pilha
Cada chamada de função empilha um quadro de pilha. Quando a função retorna, o quadro é desempilhado automaticamente.
voidb(void) { int y = 20; } // b's framevoida(void) { int x = 10; b(); } // a's frameintmain(void) { a(); return0; }
Pilha quando main → a() → b() está em andamento:
quadro de b() (y=20) ← topo (empilhado por último)
quadro de a() (x=10)
quadro de main()
Quando b() retorna, seu quadro é desempilhado; depois a() retorna e seu quadro também é desempilhado.
O que é um estouro de pilha? Recursão excessiva ou chamadas profundamente aninhadas podem esgotar a região da pilha, disparando uma falha de segmentação.
Tempos de vida explicados pelas regiões de memória
Curta duração = Pilha
Variáveis locais. Desaparecem no momento em que a função termina. Rápido, mas não persistem entre chamadas.
Longa duração = Data/BSS
Globais e static. Vivem pelo programa inteiro. Sempre acessíveis, mas abusar delas atrapalha a manutenção.
Flexível = Heap
Alocada com malloc e liberada com free. Você controla o tamanho e o tempo de vida. Esquecer de liberar gera vazamento de memória.
Experimente você mesmo — escopo
scope.c
Saída
Clique em Executar...
💡 Tente também estas ideias
Modifique uma variável global a partir de várias funções diferentes
Use uma variável local static para rastrear o número de chamadas
Sombreie uma global com uma variável local de mesmo nome