Muuttujien lisääminen
Tallentakaa ja palauttakaa arvoja.
Muuttujien lisääminen on ilmainen C Academy-oppitunti CoddyKitissä. Tämä on oppitunti 4/4. Voit lukea koko oppitunnin alta ilmaiseksi ja harjoitella sen jälkeen käytännössä selaimessa sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla. Oppitunti kuuluu C Academy-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. C Academy-kurssilla on yhteensä 4 oppituntia.
Aritmetiikan tuolle puolen
Jotta x = 5 ja myöhemmin x + 1 voidaan tukea, tulkki tarvitsee tunnisteet ja paikan niiden arvojen tallentamiseen. Tätä tallennuspaikkaa kutsutaan ympäristöksi.
Laajennamme leksikaalista analysaattoria, jäsennintä ja evaluatoria käsittelemään nimiä ja sijoituksia.
Tunnisteiden leksikaalinen analyysi
Tunniste alkaa kirjaimella tai alaviivalla ja jatkuu kirjaimilla, numeroilla tai alaviivoilla. Kopioimme nimen tokeniin.
Kiinteän kokoinen puskuri pitää esimerkin yksinkertaisena; oikeat leksikaaliset analysaattorit internöivät nimet.
#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;
}Muuttujasolmu
AST saa kaksi uutta solmutyyppiä: muuttujaviitteen ja sijoituksen. Kumpikin tallentaa muuttujan nimen.
Sijoitus säilyttää lisäksi lausekkeen, jonka arvon se tallentaa.
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;Ympäristö
Ympäristö yhdistää nimet arvoihin. Pienelle tulkille riittää yksinkertainen nimien ja arvojen pareista koostuva lineaarinen taulukko.
Suuremmissa kielissä käytetään hajautustauluja vakioajan O(1) hakuun ja sisäkkäisiin näkyvyysalueisiin.
#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 */Muuttujan arvon asettaminen
Sijoitus joko päivittää olemassa olevaa paikkaa tai lisää uuden. Lineaarinen haku pitää koodin lyhyenä.
Tallennetun arvon palauttaminen mahdollistaa sijoitusten käytön lausekkeina, kuten 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;
}Muuttujan lukeminen
Haku etsii nimen ja palauttaa sen arvon. Määrittelemättömään muuttujaan viittaaminen on ajonaikainen virhe.
Kun tämä havaitaan tässä vaiheessa, saadaan selkeä ilmoitus roska-arvon palauttamisen sijaan.
#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);
}Sijoituksen jäsentäminen
Sijoituksella on pienin etusija, ja se on oikealle assosiatiivinen. Jäsennämme faktorin; jos se on yksittäinen tunniste, jota seuraa =, muodostamme assign-solmun.
Muussa tapauksessa tunniste on pelkkä muuttujan luku.
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();
}Muuttujien evaluointi
Evaluatoriin lisätään kaksi tapausta. Muuttujasolmu hakee nimensä ympäristöstä; assign-solmu evaluoi arvolausekkeensa ja tallentaa tuloksen.
Molemmat käyttävät uudelleen apufunktioita env_get ja 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;
}Toimiva REPL-vaihe
Tämä ohjelma tallentaa muuttujan ja lukee sen sitten takaisin lausekkeessa — kaikki ympäristön kautta. Se mallintaa oikean tulkin yhtä riviä.
Suorittakaa ohjelma nähdäksenne, miten sijoitus ja haku toimivat yhdessä.
#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;
}Näkyvyysalueet ja peittäminen
Yksi tasainen ympäristö on globaali. Oikeat kielet lisäävät sisäkkäiset näkyvyysalueet, jotta funktion paikalliset muuttujat eivät peitä ulompia nimiä.
Tämä toteutetaan ketjuttamalla ympäristöjä: haku etenee sisimmästä näkyvyysalueesta ulospäin.
typedef struct Env {
char names[MAX_VARS][32];
int values[MAX_VARS];
int count;
struct Env *parent; /* enclosing scope */
} Env;Mihin seuraavaksi?
Kun muuttujat ovat käytössä, voitte lisätä lauseita, ehtolauseita ja funktioita. Kukin niistä on uusi solmutyyppi sekä sitä vastaava eval-tapaus.
Tästä eteenpäin sama leksikaalisen analysaattorin, jäsentimen ja evaluatorin muodostama putki skaalautuu oikeaksi pieneksi kieleksi.
Pikatarkistus
Pohdi, mistä ympäristö vastaa.
Kertaus
Lisäsitte leksikaaliseen analysaattoriin tunnisteet, AST:hen var- ja assign-solmut, set- ja get-operaatiot sisältävän ympäristön sekä eval-tapaukset lukemista ja sijoituksia varten.
Tulkki muistaa nyt tilan — tämä on lauseiden ja funktioiden perusta.
Opi C tekoälytuutorin avulla — ilmaiseksi
Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.
- Kurssit
- 39
- Oppitunnit
- 144
Usein kysytyt kysymykset
Onko oppitunti ”Muuttujien lisääminen” ilmainen?
Kyllä – oppitunnin ”Muuttujien lisääminen” koko tekstin voi lukea täällä verkossa ilmaiseksi. Jos haluat harjoitella interaktiivisesti sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla sekä avata koko C Academy-kurssin, päivitä CoddyKit PROhon. C Academy-kurssilla on yhteensä 4 oppituntia.
Mitä opin oppitunnilla ”Muuttujien lisääminen”?
Tallentakaa ja palauttakaa arvoja. Harjoittelet C Academy-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.
Tarvitsenko kokemusta aloittaakseni C Academy-opiskelun?
Aiempi kokemus ei ole tarpeen. CoddyKitin C Academy-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 4/4.
Kuinka kauan ”Muuttujien lisääminen”-oppitunnin suorittaminen kestää?
Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.
Voinko kirjoittaa ja suorittaa koodia tällä C Academy-oppitunnilla?
Kyllä. Jokainen C Academy-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.
Kaikki tämän kurssin oppitunnit
- Syötteen tokenisointi
- Lausekkeiden jäsentäminen
- Puun evaluointi
- Muuttujien lisääminen