发现中文版《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 }
总之两个方法都可以,不知道是原著的错误,还是出版社校准的错误,希望大家能看出来。