发现中文版《C Primer Plus第五版》示例程序的一个错误

错误的程序出现再第17章的499页ListItemCount()和500页的Traverse()两个函数上。

原著包含所有函数定义的list.c如下:

 

 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 #include "list.h"
 4 
 5 static void CopyToNode(Item item,Node * pnode);
 6 
 7 void InitializeList(List * plist)
 8 {
 9     *plist = NULL;//movie = NULL
10 }
11 
12 bool ListIsEmpty(const List * plist)
13 {
14     if(*plist==NULL)
15         return true;
16     else
17         return false;
18 }
19 
20 bool ListIsFull(const List * plist)
21 {
22     Node * pt;
23     bool full;
24     pt = (Node *)malloc(sizeof(Node));
25     if(pt==NULL)
26         full = true;
27     else
28         full = false;
29     free(pt);
30     return full;
31 }
32 
33 
34 unsigned int ListItemCount(const List * plist)
35 {
36     unsigned int count = 0;
37     Node * pnode = *plist;
38 
39     while(pnode!=NULL)
40     {
41         ++count;
42         pnode = pnode->next;
43     }
44     return count;
45 }
46 
47 
48 bool AddItem(Item item,List *plist)
49 {
50     Node * pnew;
51     Node * scan = *plist;
52 
53     pnew = (Node *)malloc(sizeof(Node));
54     if(pnew == NULL)
55         return false;
56 
57     CopyToNode(item,pnew);
58     pnew->next = NULL;
59     if(scan==NULL)
60         *plist = pnew;
61     else
62     {
63         while(scan->next!=NULL)
64             scan = scan->next;
65         scan->next = pnew;
66     }
67     return true;
68 }
69 
70 
71 void Traverse(const List * plist,void(*pfun)(Item item))
72 {
73     Node * pnode = *plist;
74     while(pnode!=NULL)
75     {
76         (*pfun)(pnode->item);
77         pnode = pnode->next;
78     }
79 }
80 
81 
82 void EmptyTheList(List * plist)
83 {
84     Node * psave;
85     while(*plist!=NULL)
86     {
87         psave = (*plist)->next;
88         free(*plist);
89         *plist = psave;
90     }
91 }
92 
93 
94 
95 static void CopyToNode(Item item,Node * pnode)//静态函数限制该函数只能在本文件内使用
96 {
97     pnode->item = item;
98 }

 

但是在film3.c中调用的形式分别如下:

 

1 Traverse(movies,showmovies);                                                //传递的是movies指针的拷贝
2 
3 printf("You entered %d movies.\n",ListItemCount(movies));     //传递的也是movies指针的拷贝

 

也就是说,函数调用的时候已经传递的是指针了,但函数体内调用时却又把它当成指针的地址,及指向指针的指针,从而发生错误

解决的方法有两个,一是更改函数调用如下:

 

1 Traverse(&movies,showmovies);                                 //传递的是movies指针的地址
2 
3 printf("You entered %d movies.\n",ListItemCount(&movies));//传递的也是movies指针的地址

 

二是更改这两个函数的函数体:

 

 1 unsigned int ListItemCount(const List * plist)
 2 {
 3     unsigned int count = 0;
 4     Node * pnode = plist;
 5 
 6     while(pnode!=NULL)
 7     {
 8         ++count;
 9         pnode = pnode->next;
10     }
11     return count;
12 }
13 
14 void Traverse(const List * plist,void(*pfun)(Item item))
15 {
16     Node * pnode = plist;
17     while(pnode!=NULL)
18     {
19         (*pfun)(pnode->item);
20         pnode = pnode->next;
21     }
22 }

 

总之两个方法都可以,不知道是原著的错误,还是出版社校准的错误,希望大家能看出来。

 

posted @ 2014-08-26 21:10  木子可  阅读(1115)  评论(2编辑  收藏  举报