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