所以我试图实现以下内容;
// Destructive Abstract data type ilist
struct ilist_ADT;
typedef struct ilist_ADT *ilist;
// prototype for secret implementation
// do not rely on ilist being a pointer
ilist iempty();
// returns an empty ilist
int iempty_huh(ilist il);
// returns 1 (true) if il is empty
// returns 0 (false) if il is not empty
int ifirst(ilist il);
// returns the first element in il
// il must not be empty
ilist icons_destroy(int in, ilist il);
// returns an ilist with in added as the first element of il
// references to il cease to be valid ilists
// the result must eventually be consumed by one of:
// icons_destroy, irest_destroy, idelete
ilist irest_destroy(ilist il);
// modifies il to remove the first element, and returns the modified ilist
// frees the memory associated with the first element
// references to il cease to be valid ilists
// the result (if non-empty) must eventually be consumed by one of:
// icons_destroy, irest_destroy, idelete
ilist icopy(ilist il);
// returns a new copy of il that continues to be a valid
// ilist with the same elements even when il is destroyed
// the result must eventually be consumed by one of:
// icons_destroy, irest_destroy, idelete
int ilength(ilist il);
// computes the number of elements in il
void idelete(ilist il);
// frees the storage for ilist
// all further references to il become invalid
// NOTE: every ilist created by icons_destroy or
// irest_destroy or icopy must eventually be destroyed
// by being consumed by icons_destroy or
// irest_destroy or idelete
我首先关注图标,我有一个非破坏性的图标,如:
ilist icons(int in, ilist il) {
ilist r = malloc(sizeof(struct ilist_ADT));
r->first = in;
r->rest = il;
r->length = 1 + ilength(il);
return r;
}
我究竟如何才能使其适应实施?换句话说,我如何使其具有破坏性?
答案 0 :(得分:1)
“破坏性”意味着允许修改函数(或oop方法中的接收者)的参数。非破坏性函数意味着它不会修改其参数,而是返回修改后的副本。允许破坏性功能的优点是,您不必创建该副本,因此您通常需要更少的malloc(在此示例中,数量相同)。
在您提供的icons
的实现中,您可以看到同意条目使原始ilist il
保持有效的未修改列表!:使用ilist il
的任何人都不会注意到您执行了此操作任何事情(当然这只适用于单链表)。
破坏性实现首先允许修改参数,但暗示你应该以有意义的方式修改参数:你应该修改它仍然引用原始ilist il
的人应查看您的修改。你可以这样做:
// observation: the names are not the best, i would call it destructiveICons
// (and ->first should be called ->value)
ilist icons_destroy(int in, ilist il) {
ilist second = malloc(sizeof(struct ilist_ADT));
second->length = il->length
second->first = il->first
second->rest = il->rest;
il->length += 1;
il->rest = second;
il->first = in;
return il;
}
现在持有ilist il
引用的其他人会看到新的第一个元素后跟旧的先前元素。
答案 1 :(得分:0)
我认为这种实施可以被视为具有破坏性(虽然我并不真正理解“破坏性”的意义)。
当使用动态分配的数据结构(在不收集垃圾的语言中)时,最重要的问题是谁负责最终释放数据。使用icons
实现时,必须使用新句柄完成发布,不要使用旧句柄。从这个意义上讲,旧句柄不再有效。
你可以改变一些东西,所以旧手柄真的无法使用。您可以添加一个字段,指示ilist
是否是链中的第一个,并在添加/删除元素时保留它。如果给出的句柄不是第一个,那么所有的API都可以拒绝工作。