Adicionando variáveis
Armazene e recupere valores.
Adicionando variáveis é uma aula grátis de C Academy no CoddyKit. Esta é a aula 4 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de C Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de C Academy inclui 4 aulas no total.
Além da aritmética
Para aceitar x = 5 e depois x + 1, o interpretador precisa de identificadores e de um lugar para armazenar seus valores. Esse armazenamento é o ambiente.
Estenderemos o analisador léxico, o analisador sintático e o avaliador para tratar nomes e atribuições.
Analisando identificadores
Um identificador começa com uma letra ou sublinhado e continua com letras, dígitos ou sublinhados. Copiamos o nome para o token.
Um buffer de tamanho fixo mantém o exemplo simples; analisadores léxicos reais internam os nomes.
#include <ctype.h>
#include <string.h>
typedef struct { TokKind kind; int value; char name[32]; } Token;
static Token lex_ident(void) {
Token t; t.kind = TOK_IDENT; int i = 0;
while (isalnum((unsigned char)peek()) || peek() == '_')
if (i < 31) t.name[i++] = advance(); else advance();
t.name[i] = '\0';
return t;
}Um nó de variável
A AST ganha dois tipos de nós: uma referência a variável e uma atribuição. Cada um armazena o nome da variável.
A atribuição também mantém a expressão cujo valor armazena.
typedef struct Node {
enum { N_NUM, N_BINOP, N_VAR, N_ASSIGN } kind;
int value; char op; char name[32];
struct Node *left, *right; /* assign uses right as value expr */
} Node;O ambiente
O ambiente associa nomes a valores. Um simples vetor linear de pares nome/valor é suficiente para um interpretador pequeno.
Linguagens maiores usam tabelas de dispersão para obter busca O(1) e escopos aninhados.
#define MAX_VARS 64
typedef struct {
char names[MAX_VARS][32];
int values[MAX_VARS];
int count;
} Env;
static Env env; /* global for this tiny example */Atribuindo a uma variável
A atribuição atualiza uma posição existente ou acrescenta uma nova. A busca linear mantém o código curto.
Retornar o valor armazenado permite usar atribuições como expressões, por exemplo y = (x = 3).
#include <string.h>
static int env_set(const char *name, int v) {
for (int i = 0; i < env.count; i++)
if (strcmp(env.names[i], name) == 0) {
env.values[i] = v; return v;
}
strcpy(env.names[env.count], name);
env.values[env.count] = v;
env.count++;
return v;
}Lendo uma variável
A busca percorre os nomes e retorna o valor correspondente. Referenciar uma variável não definida é um erro em tempo de execução.
Detectar isso aqui produz uma mensagem clara em vez de retornar um valor inválido.
#include <stdio.h>
#include <stdlib.h>
static int env_get(const char *name) {
for (int i = 0; i < env.count; i++)
if (strcmp(env.names[i], name) == 0)
return env.values[i];
fprintf(stderr, "undefined variable: %s\n", name);
exit(1);
}Analisando uma atribuição
A atribuição tem a menor precedência e é associativa à direita. Analisamos um fator; se ele for um identificador isolado seguido de =, construímos um nó de atribuição.
Caso contrário, o identificador é apenas uma leitura de variável.
static Node *parse_assign(void) {
if (cur().kind == TOK_IDENT) {
char saved[32]; strcpy(saved, cur().name);
bump();
if (cur().kind == TOK_ASSIGN) {
bump();
Node *val = parse_assign();
return assign_node(saved, val);
}
return var_node(saved); /* not an assignment */
}
return parse_expr();
}Avaliando variáveis
O avaliador ganha dois casos. Um nó de variável procura seu nome no ambiente; um nó de atribuição avalia sua expressão de valor e a armazena.
Ambos reutilizam os auxiliares env_get e env_set.
int eval(Node *n) {
switch (n->kind) {
case N_NUM: return n->value;
case N_VAR: return env_get(n->name);
case N_ASSIGN: return env_set(n->name, eval(n->right));
case N_BINOP: {
int l = eval(n->left), r = eval(n->right);
switch (n->op) {
case '+': return l + r; case '-': return l - r;
case '*': return l * r; case '/': return l / r;
}
}
}
return 0;
}Uma etapa funcional do REPL
Este programa armazena uma variável e depois a lê novamente em uma expressão — tudo por meio do ambiente. Ele modela uma linha de um interpretador real.
Execute-o para ver a atribuição e a busca trabalhando em conjunto.
#include <stdio.h>
#include <string.h>
#define MAX_VARS 64
static char names[MAX_VARS][32];
static int values[MAX_VARS];
static int count;
static int env_set(const char *n,int v){
for(int i=0;i<count;i++) if(!strcmp(names[i],n)){values[i]=v;return v;}
strcpy(names[count],n); values[count]=v; count++; return v;
}
static int env_get(const char *n){
for(int i=0;i<count;i++) if(!strcmp(names[i],n)) return values[i];
return 0;
}
int main(void){
env_set("x", 5); /* x = 5 */
int r = env_get("x") + 1; /* x + 1 */
printf("x = %d\n", env_get("x"));
printf("x + 1 = %d\n", r);
return 0;
}Escopos e ocultação
Um único ambiente plano é global. Linguagens reais adicionam escopos aninhados para que as variáveis locais de uma função não sobrescrevam nomes externos.
O senhor implementa isso encadeando ambientes: a busca percorre do escopo mais interno para os externos.
typedef struct Env {
char names[MAX_VARS][32];
int values[MAX_VARS];
int count;
struct Env *parent; /* enclosing scope */
} Env;Para onde seguir
Com as variáveis prontas, o senhor pode adicionar instruções, condicionais e funções. Cada um é um novo tipo de nó mais um caso em eval.
A partir daqui, o mesmo fluxo de análise léxica, análise sintática e avaliação pode crescer até se tornar uma pequena linguagem real.
Verificação rápida
Pense pelo que o ambiente é responsável.
Recapitulação
O senhor adicionou identificadores ao analisador léxico, nós de variável e atribuição à AST, um ambiente com definição e leitura, além de casos em eval para leituras e atribuições.
Agora o interpretador memoriza estado — a base para instruções e funções.
Perguntas Frequentes
A aula “Adicionando variáveis” é grátis?
Sim — o texto completo de “Adicionando variáveis” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de C Academy, atualize para CoddyKit PRO. O curso de C Academy inclui 4 aulas no total.
O que vou aprender em “Adicionando variáveis”?
Armazene e recupere valores. Você pratica C Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar C Academy?
Nenhuma experiência prévia é necessária. C Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 4 de 4.
Quanto tempo leva a aula “Adicionando variáveis”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de C Academy?
Sim. Cada aula de C Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- Tokenizando a entrada
- Analisando expressões
- Avaliando a árvore
- Adicionando variáveis