변수 추가하기
값을 저장하고 다시 불러와 보세요.
변수 추가하기은(는) CoddyKit의 무료 C Academy 강의입니다. 이것은 4개 중 4번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 C Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. C Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
산술을 넘어서
x = 5와 이후의 x + 1을 지원하려면 인터프리터에 식별자와 그 값을 저장할 장소가 필요합니다. 이 저장소가 환경입니다.
이름과 할당을 처리하도록 어휘 분석기, 구문 분석기, 평가기를 확장하겠습니다.
식별자 어휘 분석하기
식별자는 문자나 밑줄로 시작하고, 뒤에 문자, 숫자 또는 밑줄이 이어집니다. 이름을 토큰에 복사합니다.
고정 크기 버퍼를 사용하면 예제를 단순하게 유지할 수 있습니다. 실제 어휘 분석기는 이름을 인터닝합니다.
#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;
}변수 노드
AST에 두 가지 노드 종류가 추가됩니다. 변수 참조와 할당입니다. 각각 변수 이름을 저장합니다.
할당은 저장할 값을 가진 표현식도 보관합니다.
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(1) 조회와 중첩된 범위를 위해 해시 테이블을 사용합니다.
#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 */변수 설정하기
할당은 기존 슬롯을 갱신하거나 새 슬롯을 추가합니다. 선형 검색을 사용하면 코드가 짧아집니다.
저장된 값을 반환하면 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;
}변수 읽기
조회는 이름을 검색하여 그 값을 반환합니다. 정의되지 않은 변수를 참조하면 실행 시간 오류가 발생합니다.
이곳에서 이를 잡으면 쓰레기 값을 반환하는 대신 명확한 메시지를 표시할 수 있습니다.
#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);
}할당 구문 분석하기
할당은 가장 낮은 우선순위를 가지며 오른쪽 결합입니다. 인수를 구문 분석한 다음, 그것이 = 뒤에 오는 단독 식별자라면 assign 노드를 만듭니다.
그렇지 않으면 해당 식별자는 단순한 변수 읽기입니다.
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();
}변수 평가하기
평가기에 두 가지 경우가 추가됩니다. 변수 노드는 환경에서 이름을 조회하고, assign 노드는 값 표현식을 평가하여 저장합니다.
두 경우 모두 env_get과 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;
}작동하는 REPL 단계
이 프로그램은 변수를 저장한 다음 표현식에서 다시 읽습니다. 모든 과정이 환경을 통해 이루어집니다. 실제 인터프리터의 한 줄을 모델링한 것입니다.
실행하여 할당과 조회가 함께 작동하는 모습을 확인해 보세요.
#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;
}범위와 이름 가리기
하나의 평평한 환경은 전역 환경입니다. 실제 언어에서는 중첩된 범위를 추가하여 함수의 지역 변수가 바깥쪽 이름을 덮어쓰지 않도록 합니다.
환경을 연결하여 이를 구현합니다. 조회는 가장 안쪽 범위에서 바깥쪽으로 이동합니다.
typedef struct Env {
char names[MAX_VARS][32];
int values[MAX_VARS];
int count;
struct Env *parent; /* enclosing scope */
} Env;다음 단계
변수를 마련했으므로 문장, 조건문, 함수를 추가할 수 있습니다. 각각은 새로운 노드 종류와 eval 처리 사례를 추가하는 방식입니다.
이제부터 동일한 어휘 분석기-구문 분석기-평가기 처리 흐름을 실제 작은 언어로 확장할 수 있습니다.
빠른 확인
환경이 어떤 책임을 맡는지 생각해 보세요.
복습
어휘 분석기에 식별자를 추가하고, AST에 var/assign 노드를 추가했으며, 설정과 조회가 가능한 환경과 읽기 및 할당을 위한 eval 처리 사례를 추가했습니다.
이제 인터프리터가 상태를 기억합니다. 이는 문장과 함수를 위한 기반입니다.
자주 묻는 질문
“변수 추가하기” 강의는 무료인가요?
네 — “변수 추가하기” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 C Academy 강의 전체를 잠금 해제할 수 있습니다. C Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
“변수 추가하기”에서 뭘 배우나요?
값을 저장하고 다시 불러와 보세요. 브라우저에서 직접 실행하는 실습 코드로 C Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
C Academy을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 C Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 4번째 강의입니다.
“변수 추가하기” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 C Academy 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 C Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.