下面就是这份考卷
中级 LPC 程式基本能力测验
本试题共有 25 大题,每大题 4 分,测验时间为 24 小时,准许翻阅任何资料,询问他人
,无论任意方式达成作答目的者均被允许,但切忌不知所云的胡乱复制不相关的程式作答
,或是随便剪下一段参考资料内容贴上来作答,违者该题不予计分。此试题并不牵涉于「
效率」、「进阶流程控制」以及「演算法」的考虑和设计阶段,仅测验对于 MudOS 所提供
之 LPC 语言的熟练度和相关知识,以及与 LPC 相关的一些 MudOS 本身之动作和行为,另
外,可能会测验一些程式写作上被要求的一些基本习惯。
此试题适合系统架构者(system architect - arch)之中级以上之巫师作答,满分 100 分,
及格分数为 60 分。
--------------------------------------------------------------------------------
1. (1) LPC 中的条件叙述结果为非零值时代表的意义为何? (1%)
(2) 如何取出一个字串中第 2 到第 7 个字之间的字串(含第 2 及第 7 个字元)? (1%)
(3) 观察以下程式码:
mapping m;
void create()
{
m["id"] = 10;
}
试问此程式码何处有误?应如何修改? (1%)
(4) 如果不希望物件中某个全域变数被 save_object 这个 efun 所储存,该如
何宣告变数? (1%)
--------------------------------------------------------------------------------
2. [题组] LPC 提供物件储存资料内容的功能,则:
(1) 试列出 LPC 支援之资料型别名称。 (1%)
(2) 哪些资料型别可被 MudOS 内建之 efun 所储存? (1%)
(3) 哪些资料型别无法被 MudOS 内建之 efun 所储存? (1%)
(4) 承上题,试说明这些资料型别无法被储存之可能原因。 (1%)
--------------------------------------------------------------------------------
3. [题组] LPC 之函示呼叫提供 call by reference 的方式,试问:
(1) 哪些资料型态在呼叫时预设为 call by reference? (1%)
(2) 如何使这些资料型别之变数在传递时模拟 call by value? (1%)
(3) 自动 call by reference 之变数在其所呼叫的目的函式中,有可能经由
assignment operator 消除其 reference 的关系,试举出一个例子。 (1%)
(4) 试撰写一个 swap_value 函式,以 call by reference 的方式交换传入之两
引数内容值,该函式传回型别为 void。 (1%)
--------------------------------------------------------------------------------
4. MudOS 为物件为基本元素所组成之系统,试问:
(1) load_object 与 new 这两个 efun 所传回之物件有何不同? (1%)
(2) 物件名称是否一定与程式档案名称有关?试说明原因。 (1%)
(3) 当一个物件 A 被 shadow 到物件 B,且两者均有一名称为 func 之函式时,
在何种情况下仍能使用 call_other 方式呼叫 B 中被遮蔽之函式? (1%)
(4) 一个物件中的程式码如果将自己摧毁,是否会立即停止程式执行?有什么该
注意的地方? (1%)
--------------------------------------------------------------------------------
5. [题组] LPC 中支援 function pointer 的资料型别,试问
(1) 每个 function pointer 指向一个函式后,会自动被指定一个 owner,请问
该如何强制变更其 owner? (1%)
(2) 试利用上题的方式,于物件 A 中撰写一段程式码,以 fetch_variable 这个
efun 取得物件 B 中的全域变数内容值。 (1%)
(3) function pointer 的操作可以使用 (: func(ob, $1) :) 的语法来指定执行
此 function pointer 时的引数传递方式,试说明 $1 的作用。 (1%)
(4) 承上题,如果 ob 为 local variable,会因为程式执行离开其有效范围后消
失,因此 MudOS compiler 会在编译时段产生错误讯息,试修改上题之语法
使其能够正常运作。 (1%)
(5) 一个 function pointer 的 owner 被摧毁后,执行此 function pointer 将
会发生执行期错误,试问该如何避免此错误发生?
--------------------------------------------------------------------------------
6. [题组] LPC 提供物件继承的功能,试问:
(1) 假设 A 继承 B,两者中均有同名函式 func 时,A 该如何呼叫 B 中的 func?
(1%)
(2) 承上题,如果希望 B 中函式 func,不能被继承 B 的物件所覆盖,或是不希望
被其他物件以 shadow 覆盖,应如何宣告此函式? (1%)
(3) 试说明修饰字 private 及 protected 在继承上的影响性。 (1%)
(4) 若 A 继承 B,且 A 继承 C,但 B 与 C 并无继承关系,仅同时被 A 所继承,
如果 C 中有一 private function 名称为 func,该如何于 B 中撰写程式码以
呼叫 C 中的 func? (1%)
--------------------------------------------------------------------------------
7. MudOS 中提供了一些 driver apply functions,试问:
(1) 哪个 interactive apply function 负责处理使用者的一般性输入? (1%)
(2) 哪个 master apply function 负责处理使用者由外面连线进入时,使该连线
与某个物件连结使其成为 interactive object? (1%)
(3) 哪些 valid_ 系列的 master apply function 在不定义时自动视为允许? (1%)
(4) 哪个 interactive apply function 负责处理由 message 这个 efun 所传送
之讯息? (1%)
--------------------------------------------------------------------------------
8. MudOS 中有一防止程式掉入无穷回圈,而有一个 evaluation cost 值,其值在每
次 LPC 程式执行到结束期间,每执行一个指令码就会减一,每次执行结束后将被
重设为最大值,当其归零时发生一个 Too long evaluation 的错误以终止程式执
行,然而有些时候需要执行指令量特别高的程式,请写出三种于这种特殊情形下
仍能使此种程式正常运作的方式。 (4%)
--------------------------------------------------------------------------------
9. LPC 中对 type 3 grammar 以 regular expression 的方式支援,其中 regexp
这个 efun 提供字串及字串阵列的比对搜寻,而 sscanf 中也支援它以便于辅助
拆解一个字串,试回答下列问题:
(1) 试用 regexp 撰写一段程式码,于一个字串阵列中取出小写 t 开头的所有
elements。 (2%)
(2) 试用 sscanf 配合 regular expression 消除一字串开头的空白。 (2%)
--------------------------------------------------------------------------------
10. MudOS 中有一部份是提供编译 LPC 程式码,将物件载入记忆体及释放的功能,
试问:
(1) MudOS 编译 LPC 程式码的时机为何? (1%)
(2) 一个物件的程式档案开头有一行 #pragma save_binary 对于物件载入的动
作有何影响? (1%)
(3) 当一个物件被载入后,其非复制物件(即广义上物件名称无 # 号的物件)称
为原始物件,其在记忆体中占有资料区块和程式区块,复制物件则无程式
区块,程式部分参考著原始物件的程式区块。请问当原始物件被摧毁并重
新被载入后,原先的复制物件使用的是新的程式区块还是旧的程式区块?
(1%)
(4) 试写一段程式码,摧毁一个原始物件以及其所有的复制物件。 (1%)
--------------------------------------------------------------------------------
11. [题组] LPC 中的 present efun 提供寻找物件的功能,试问:
(1) 使用 present 在许多物件中寻找一个物件时,会逐一呼叫每个物件中的那
个 apply function? (1%)
(2) 承上题,如果这些物件中有三个物件符合搜寻条件,那么该如何取得第二
个相符的物件? (1%)
(3) 请用一些文字叙述假设一些物件的环境,并撰写一些程式码,说明 present
的动作。 (1%)
--------------------------------------------------------------------------------
12. [题组] MudOS 提供了各种错误的处理和记录功能,试问:
(1) 哪个 master apply function 在 compilation error 发生时会自动被呼叫?
(1%)
(2) 哪个 master apply function 在 runtime error 发生时会自动被呼叫? (1%)
(3) 承上题,当此 apply function 在执行时也发生错误时,MudOS 会如何处理?
(1%)
(4) 承上题,当 runtime error 发生时,如果该 error 发生于 catch 区块中,
此 apply function 是否仍会被呼叫? (1%)
--------------------------------------------------------------------------------
13. MudOS 会遵循一些设定而周期性的呼叫一些物件的 apply functions,请列出这些
apply functions,并说明如何使其开始被 MudOS 周期性呼叫,以及停止方式(没有
的请注明无)。 (4%)
--------------------------------------------------------------------------------
14. MudOS 所创造出来的世界之基本元素为物件,而这些物件在被产生、消灭及彼此间
的互相关系上也有许多支援,试问:
(1) 一个物件被创造出来时,哪个 function 会被 MudOS 自动呼叫? (1%)
(2) 一个物件被摧毁时,被摧毁的物件上有什么 function 会被 MudOS 自动呼叫?
(1%)
(3) 一个物件的 environment object 被摧毁时,该物件身上哪个 function 会自
动被 MudOS 呼叫? (1%)
(4) 如果希望 /obj 路径下的所有物件档案均不能被载入,且物件中任一行程式码均
没有机会被执行,应该如何作此限制? (1%)
--------------------------------------------------------------------------------
15. MudOS 的世界里物件与物件之间,有著空间上的相对关系,试问:
(1) 如果玩家物件 A 为某一房间物件的内容物(即 A 位于此房间中),应该透过什么
efun 取得此房间物件? (1%)
(2) 如果玩家物件 A 的内容物里有许多道具(即 A 身上有许多道具),我们该透过什
么 efun 一次取得这些道具的集合(即物件阵列)? (1%)
(3) 试用一些文字叙述假设几个物件环境,以及一些程式码,来说明如何移动一个物
件。 (1%)
(4) 当一个物件被移动到一个物件中之后,该物件是否还能 shadow 到另一个物件身
上? (1%)
--------------------------------------------------------------------------------
16. 试以目前所学的技术,设计一个物件程式码,其中有全域变数 basic_data、abilities
以及 magics,其型态均为 mapping,建立一些资料,并以 save_object 储存其内容至
一个档案。并设计一个指定变数回存的功能,也就是撰写一个函式,传入变数名称,该
变数之值即会被回存至上次存档时的内容。 (4%)
---------------------------------------------------------------------------------
17. 试撰写一个简易 mudlib 的几个基本物件程式码,使这个 mudlib 能够提供基本连线,
在连线成功后,可用 edit <filename> 的指令格式编辑档案,以 update <filename>
来将 filename 所产生的原始物件摧毁,并重新载入,以 quit 指令离线,并且能使用
shutdown 指令关闭 mud (请记得标明档名,以及这些档案在 runtime configuration
file 中的定义)。 (4%)
--------------------------------------------------------------------------------
18. 目前有一个函式,其传入值代表整数型态,代表输入模式,并以 switch case 述句来
判断其值,以执行相关程式码,其值为 1 时代表进行单行输入,为 2 时代表多行输入
,为 3 时代表不处理输入(即拦截),其它情形则发生错误,此函式内容如下:
void start_input(int mode)
{
switch(mode) {
case 1:
// some codes for single line input...
return;
case 2:
// some codes for multi line input...
return;
case 3:
return;
default:
error("No handler for this input mode.\n");
}
}
很明显的此程式码可读性不佳,尤其在使用上,呼叫部分使用 start_input(1)、
start_input(2)等等的方式容易使人无法立即理解,且容易误传其它无效的值进
入,试修改及增加一些程式码,使其更容易阅读,且在使用上较不容易传入无意
义值。 (4%)
--------------------------------------------------------------------------------
19. 有一未经缩排处理的程式码如下:
void do_something()
{
int a, b, c, d, e, f, g, h;
if(!a) a = 10;
b = 5;
if(b)
if(!c)
c = 3;
else
b = 10;
else
b = 20;
h = 16;
for(d=0;d<5;d++)
for(e=0;e<5;e++)
f = 100;
g += f;
}
试将此程式码作正确的缩排处理,使其层次正确以便于区分 if、else、for 述句之
影响范围。 (4%)
--------------------------------------------------------------------------------
20. [题组] LPC 的 function pointer 提供指向 anonymous function 的功能,则:
(1) 试撰写一段程式码,将一个 function pointer 变数指向一个 anonymous
function,该 anonymous function 接受 2 个整数值输入,回传结果为两传
入变数之和 (2%)
(2) 将此 function pointer 的 owner 设定给 this_player()。 (1%)
(3) 最后再撰写一行执行此 function pointer 的范例程式码。 (1%)
--------------------------------------------------------------------------------
21. [题组] LPC 中的 0 分为两种,一种是常数零值 (constant zero),一种是未定义之
常数零值(constant zero & undefined),试问:
(1) LPC 中的变数,分别在什么情况下会有这两种不同的 0 值? (1%)
(2) 我们该如何测试该变数目前是哪种 0 值? (1%)
(3) 此二种 0 值在 if、while 等条件述句中代表的意义为何? (1%)
(4) 试撰写一个程式码,使一个已被指定值的 mapping 变数值,回到未定义之常数
零值。 (1%)
--------------------------------------------------------------------------------
22. 假设我们有一个房间物件,其中有一个整数 status 储存著房间的状态旗号,我们假设
status 最右边的位元(第一位元)被设定为 1 时,无法使用战斗指令。第二位元则是灯
光开关的状态,1 为点亮,0 为关闭,当我们每次按下开关时,0 与 1 会相互切换
,请设计以下几个函式:
战斗限制部分: (2%)
set_flag - 用来将 status 的某个位元设定为 1
clear_flag - 用来将 status 的某个位元设定为 0
灯光部分: (2%)
inverse_flag - 用来将 status 的某个位元由 1 转为 0,或由 0 转为 1
push_button - 按下灯光开关时会被呼叫
--------------------------------------------------------------------------------
23. (1) 请按照以下规格及功能要求设计出 simul_efun:
prototype: mixed *keys(mapping m);
当 m 为 0 值时不发生错误,传回空阵列。 (2%)
(2) 设法防止 efun::keys(m); 在 simulated external function object 之外的地
方被执行成功。 (2%)
--------------------------------------------------------------------------------
24. LPC 提供了对于 socket 的支援,试依照下列要求撰写 LPC 程式码:
(1) 建立一个 LPC 物件,并监听 port 60000,有连线产生即接受其连线,当使用者
传送讯息为「quit」时,中断此名使用者的连线,当讯息为「shutdown」时,与
此使用者终止连线,并停止监听 port 60000。 (2%)
(2) 承上题,试撰写另一物件,使其能藉由呼叫前一物件之函式,取得正在监听 port
60000 之 socket 所有权,并能持续提供相同的连线与指令处理功能。 (2%)
--------------------------------------------------------------------------------
25. LPC 提供 virtual object 的支援,带给许多便利性,如大规模的制造房间,构成整
块大陆,可由此功能完成,请作答以下问题:
(1) 试列出并撰写相关函式,以产生任一物件名称为「/domain/test/17,15」之
virtual object,此物件并不需具备任何功能,请记得标明哪个函式属于哪
些物件程式档案里。 (2%)
(2) 承上题,在此物件中宣告一字串变数,并指定其值后以 save_object 存入资料
档中,试设计一简单的自动读取程式,使此物件下次被 load_object 载入完毕
并被传回后,该字串变数已经回复到上次储存的状态。 (2%)
——————————————[End]———————————————