列表 - C(家庭作业)

时间:2012-02-11 19:43:50

标签: c list pointers

所以我试图实现以下内容;

  // 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;

}

我究竟如何才能使其适应实施?换句话说,我如何使其具有破坏性?

2 个答案:

答案 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都可以拒绝工作。