錯誤的程序出現再第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 }
總之兩個方法都可以,不知道是原著的錯誤,還是出版社校准的錯誤,希望大家能看出來。