如何修改预声明的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
相关产品推荐
相关产品推荐

