You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修改预声明的SymbolNode节点内容?赋值后值未更新原因求解

问题描述

我编写了一个模拟变量声明流程的程序,实现方案为:先创建携带类型、名称、值、作用域等级等属性的Symbol对象,再创建SymbolNode存储这些Symbol对象,最后将所有节点存入链表结构的符号表中。目前代码如下:

struct Symbol {
    Symbol() : id_name(""), type(""), value("") {}
    Symbol(string id_name, string type, string value, int level) : id_name(id_name), type(type), value(value), level(level) {}

    string id_name;
    string type;
    string value;
    int level;
};

struct SymbolNode {
    SymbolNode() : data(Symbol()), next(NULL) {}
    SymbolNode(Symbol data, SymbolNode* next) : data(data), next(next) {}

    Symbol data;
    SymbolNode* next;
};

class SymbolTable {
public:
    SymbolNode* head;
    SymbolTable() {
        head = NULL;
    }
    void run();
    void insert(Symbol symbol);
    void assign(string id_name, string value);
};

void SymbolTable::insert(Symbol symbol) {

    SymbolNode* node = new SymbolNode(symbol, nullptr);
    SymbolNode* ptr = this->head;
    if (this->head == nullptr) {
        node->next = this->head;
        this->head = node;
    }
    else {
        while (ptr->next != nullptr) ptr = ptr->next;
        ptr->next = node;
    }
}

void SymbolTable::assign(string id_name, string value) {
    SymbolNode* ptr = this->head;
    if (this->head == nullptr) cout << "error" << endl;
    while (ptr != nullptr) {
        if (ptr->data.id_name == id_name) {
            ptr->data.value = value;
            return;
        }
        else {
            ptr = ptr->next;
        }
    }
}
void SymbolTable::run() {
    Symbol symbol("x", "number", "", 0);   // 等价于 { int x; }
    insert(symbol);                        // 将x存入符号表
    assign("x", "15");                     // 预期执行 { x = 15; }

    Symbol symbol1("y", "string", "", 0);
    insert(symbol1);
    assign("y", "hello mate");
}

int main() {
    SymbolTable* st = new SymbolTable();
    st->run();
    return 0;
}

我逐步骤调试时发现,名为"x"的number类型变量的值仍然是默认的空字符串"",没有如我预期变为"15",请问出现该问题的原因是什么?

问题解答
  • 核心原因是调试时查看的对象不对。你在run函数中声明的Symbol symbol是栈上的局部变量,调用insert方法时参数为值传递,会将这个局部变量拷贝一份存入链表节点中。链表中存储的Symbol对象和原来的栈上局部变量是完全独立的两个实例,assign方法修改的是链表中存储的拷贝的值,不会影响原来的栈上局部变量。你需要查看符号表中head节点指向的data.value属性,才能看到修改后的结果。
  • 可以在assign方法修改值后添加打印语句验证结果,比如修改assign逻辑如下,即可确认赋值操作是否生效:
if (ptr->data.id_name == id_name) {
    ptr->data.value = value;
    cout << "赋值成功,变量" << id_name << "的新值为:" << ptr->data.value << endl;
    return;
}
  • 代码还有两个可优化的点:
    • assign方法中如果遍历完链表都没有找到对应名称的变量,没有任何错误提示,建议补充该场景的处理逻辑。
    • 目前没有实现作用域等级的匹配逻辑,后续如果要支持同名不同作用域的变量,需要在assign和insert时增加level属性的判断。

内容的提问来源于stack exchange,提问作者HIẾU NGUYỄN HÀ TRỌNG

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 02:39:04