Tilføj variabler
Gem og hent værdier.
Tilføj variabler er en gratis C Academy-lektion på CoddyKit. Dette er lektion 4 af 4. Du kan læse hele lektionen gratis nedenfor — og derefter øve dig praktisk i browseren med en indbygget kodeeditor og en AI-vejleder, der er tilgængelig døgnet rundt. Den er en del af læringsforløbet i C Academy, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. C Academy-kurset indeholder 4 lektioner i alt.
Ud over aritmetik
For at understøtte x = 5 og senere x + 1 har fortolkeren brug for identifikatorer og et sted at gemme deres værdier. Dette lager kaldes miljøet.
Vi udvider lexeren, parseren og evaluatoren, så de kan håndtere navne og tildeling.
Lexing af identifikatorer
En identifikator begynder med et bogstav eller en underscore og fortsætter med bogstaver, cifre eller underscores. Vi kopierer navnet ind i tokenen.
En buffer med fast størrelse holder eksemplet enkelt; virkelige lexere internérer navne.
#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;
}En variabelnode
AST'et får to nodetyper: en variabelreference og en tildeling. Begge gemmer variabelnavnet.
Tildelingen gemmer også det udtryk, hvis værdi den gemmer.
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;Miljøet
Miljøet knytter navne til værdier. Et simpelt lineært array med par af navne og værdier er tilstrækkeligt til en lille fortolker.
Større sprog bruger hashtabeller til opslag i O(1) og indlejrede scopes.
#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 */Tildeling af en variabel
En tildeling opdaterer enten en eksisterende plads eller tilføjer en ny. Lineær søgning holder koden kort.
Hvis den gemte værdi returneres, kan tildelinger bruges som udtryk, f.eks. 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;
}Læsning af en variabel
Et opslag gennemgår navnene og returnerer værdien. En reference til en udefineret variabel er en køretidsfejl.
Hvis vi fanger dette her, får vi en tydelig meddelelse i stedet for en tilfældig værdi.
#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);
}Parsing af tildeling
Tildeling har den laveste præcedens og er højreassociativ. Vi parser en faktor; hvis det er en ren identifikator efterfulgt af =, opbygger vi en assign-node.
Ellers er identifikatoren blot en variabellæsning.
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();
}Evaluering af variable
Evaluatoren får to nye tilfælde. En variabelnode slår sit navn op i miljøet, og en assign-node evaluerer sit værdiudtryk og gemmer det.
Begge genbruger hjælpefunktionerne env_get og 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;
}Et fungerende REPL-trin
Dette program gemmer en variabel og læser den derefter tilbage i et udtryk — alt sammen gennem miljøet. Det modellerer én linje i en virkelig fortolker.
Kør programmet for at se tildeling og opslag arbejde sammen.
#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;
}Scopes og skygning
Et enkelt fladt miljø er globalt. Virkelige sprog tilføjer indlejrede scopes, så en funktions lokale variable ikke overskriver navne i ydre scopes.
Det implementerer du ved at kæde miljøer sammen: opslaget går fra det inderste scope og udad.
typedef struct Env {
char names[MAX_VARS][32];
int values[MAX_VARS];
int count;
struct Env *parent; /* enclosing scope */
} Env;Hvad er næste skridt?
Med variable på plads kan du tilføje sætninger, betingelser og funktioner. Hver af dem er en ny nodetype plus et eval-tilfælde.
Herfra kan den samme lexer-parser-evaluator-pipeline skaleres til et rigtigt lille sprog.
Hurtigt tjek
Tænk over, hvad miljøet har ansvaret for.
Opsummering
Du tilføjede identifikatorer til lexeren, var/assign-noder til AST'et, et miljø med set og get samt eval-tilfælde for læsninger og tildelinger.
Fortolkeren husker nu tilstand — grundlaget for sætninger og funktioner.
Lær C med en AI-underviser — gratis
Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.
- Kurser
- 39
- Lektioner
- 144
Ofte stillede spørgsmål
Er lektionen “Tilføj variabler” gratis?
Ja — hele teksten til “Tilføj variabler” kan læses gratis her på nettet. Hvis du vil øve dig interaktivt med en indbygget kodeeditor og en AI-vejleder døgnet rundt og få adgang til resten af C Academy-kurset, skal du opgradere til CoddyKit PRO. C Academy-kurset indeholder 4 lektioner i alt.
Hvad lærer jeg i “Tilføj variabler”?
Gem og hent værdier. Du øver dig i C Academy med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.
Skal jeg have erfaring for at begynde på C Academy?
Der kræves ingen tidligere erfaring. C Academy på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 4 af 4.
Hvor lang tid tager lektionen “Tilføj variabler”?
De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.
Kan jeg skrive og køre kode i denne C Academy-lektion?
Ja. Alle C Academy-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.
Alle lektioner i dette kursus
- Tokenisering af input
- Pars udtryk
- Evaluér træet
- Tilføj variabler