C语言链表appendNode函数编写及tbaMUD obj_to_room修改求助
tbaMUD 对象掉落顺序问题及代码修复
问题背景
- 在
handler.c文件中,obj_to_room函数将房间内掉落的对象添加到链表头部,形成栈结构:先掉落的对象在链表底部(头节点),后掉落的在顶部(尾节点)。 - 在
act.informative.c文件中,look_at_room函数调用list_obj_to_char函数,通过for循环从链表尾部到头部遍历,导致显示时最新掉落的对象排在最前,最早的在最后,引发显示顺序问题。 - 目标是修改逻辑,让新掉落的对象添加到链表尾部,使显示顺序与掉落顺序一致。
编译错误分析
你编写的修改代码存在几个核心问题:
- C标准不支持嵌套函数:你在
obj_to_room内部定义appendNode函数,这不符合C语言标准(仅部分编译器有非标准扩展),直接导致编译报错。 - 类型声明错误:
struct world[room].contents*不是合法的类型声明,实际链表节点的类型是struct obj_data,world[room].contents是指向该类型的指针,代表链表头。 - 逻辑混乱:你的
appendNode函数混淆了新对象、链表头和遍历节点的关系,没有正确实现"追加到链表尾部"的逻辑。
正确修改方案
不需要额外定义appendNode函数,直接修改obj_to_room的逻辑即可实现追加到链表尾部:
修改后的obj_to_room函数
/* put an object in a room */ void obj_to_room(struct obj_data *object, room_rnum room) { if (!object || room == NOWHERE || room > top_of_world) { log("SYSERR: Illegal value(s) passed to obj_to_room. (Room #%d/%d, obj %p)", room, top_of_world, (void *)object); return; } // 初始化新对象的状态 object->next_content = NULL; IN_ROOM(object) = room; object->carried_by = NULL; if (ROOM_FLAGGED(room, ROOM_HOUSE)) { SET_BIT_AR(ROOM_FLAGS(room), ROOM_HOUSE_CRASH); } // 如果链表为空,直接作为头节点 if (world[room].contents == NULL) { world[room].contents = object; return; } // 遍历到链表尾部 struct obj_data *current = world[room].contents; while (current->next_content != NULL) { current = current->next_content; } // 将新对象追加到尾部 current->next_content = object; }
代码说明
- 先初始化新对象状态:把
next_content设为NULL(因为它会成为链表最后一个节点),设置所在房间、清空携带状态。 - 检查链表是否为空:如果是空链表,直接把新对象设为链表头。
- 遍历链表:从头节点开始,一直走到最后一个
next_content为NULL的节点。 - 追加新对象:把最后一个节点的
next_content指向新对象,完成尾部追加。
修改后,新掉落的对象会被添加到链表尾部,配合原有的遍历逻辑,显示时就会按掉落先后顺序展示(最早掉落的在前,最新的在后)。
内容的提问来源于stack exchange,提问作者Bodhi
相关产品推荐
相关产品推荐

