飘云阁

 找回密码
 加入我们

QQ登录

只需一步,快速开始

查看: 2542|回复: 1

[C/C++] 学习Nisy的C教程第30课后写的通讯录程序,欢迎来查错

[复制链接]
  • TA的每日心情
    开心
    2018-9-27 19:17
  • 签到天数: 31 天

    [LV.5]常住居民I

    发表于 2015-2-4 13:55:41 | 显示全部楼层 |阅读模式
    学习Nisy的C教程第30课后,写了个通讯录程序,用tc2编译成功,运行时末尾有一行提示:
    Null pointer assignment
    改用vc6编译,运行正常。不知问题出在哪里,请大家帮忙分析分析,谢谢。
    (感谢扎西,现已添加了一些注释)
    1. /* list3.h -- 通讯录头文件                    */
    2. /* 本通讯录的联系人姓名和手机号码串可任意长度 */

    3. #define NULL 0


    4. typedef struct
    5. {
    6.         char *name;        /* 联系人姓名 */
    7.         char *phone;        /* 手机号码 */
    8. }Contacts;

    9. #define ElementType Contacts

    10. /* #define ElementType char */

    11. typedef struct
    12. {
    13.         ElementType *pbuffer;
    14.         int nlen;        /* 当前联系人数量 */
    15.         int nmax;        /* 联系人数量上限 */
    16. }List;

    17. /* 初始化 */
    18. List * InitList(int n);

    19. /* 清除通讯录 */
    20. int DestroyList(List * lp);

    21. /* 追加联系人 */
    22. int AppendList(List * lp, ElementType *data);

    23. /* 插入联系人 */
    24. int InsertList(List * lp, ElementType *data, int n);

    25. /* 删除联系人 */
    26. int DeleteList(List * lp, int n);

    27. /* 遍历联系人 */
    28. int TraverseList(List * lp, void (*f)(ElementType *pdata));

    29. /* 读取一个联系人 */
    30. int GetElement(List * lp, ElementType *pdata, int n);
    复制代码

    1. /* list3.c -- 通讯录文件                      */
    2. /* 本通讯录的联系人姓名和手机号码串可任意长度 */

    3. #include"List3.h"

    4. /* 初始化通讯录 */
    5. List * InitList(int n)
    6. {
    7.         List * lp = NULL;
    8.         lp = (List *)malloc(sizeof(List));
    9.         if(!lp)
    10.         {
    11.                 return lp;
    12.         }
    13.         lp->pbuffer = (ElementType *)malloc(sizeof(ElementType) * n);
    14.         if (!lp->pbuffer)
    15.         {
    16.                 free(lp);
    17.                 lp = NULL;
    18.                 return lp;
    19.         }
    20.         lp->nmax = n;
    21.         lp->nlen = 0;
    22.         return lp;
    23. }

    24. /* 清除通讯录 */
    25. int DestroyList(List * lp)
    26. {
    27.         int i;
    28.         if (lp)
    29.         {
    30.                 for (i = 0; i < lp->nlen; i++)
    31.                 {
    32.                         if (lp->pbuffer[i].name) free(lp->pbuffer[i].name);
    33.                         if (lp->pbuffer[i].phone) free(lp->pbuffer[i].phone);
    34.                 }
    35.                 /* if (lp->pbuffer) free(lp->pbuffer); */
    36.                 if (lp) free(lp);
    37.         }
    38.         return 1;
    39. }

    40. /* 追加联系人 */
    41. int AppendList(List * lp, ElementType *pdata)
    42. {
    43.         int nlen;
    44.         if (lp->nlen >= lp->nmax)
    45.         {
    46.                 printf("\nList is already full!\n");
    47.                 return 0;
    48.         }

    49.         /* 每个联系人单独申请空间,这样联系人姓名和手机号就可以不限定长度了 */
    50.         nlen = strlen(pdata->name);
    51.         lp->pbuffer[lp->nlen].name = (char *)malloc(nlen + 1);
    52.         if (!(lp->pbuffer[lp->nlen].name))
    53.         {
    54.                 return 0;
    55.         }
    56.         memset(lp->pbuffer[lp->nlen].name, 0, nlen + 1);

    57.         nlen = strlen(pdata->phone);
    58.         lp->pbuffer[lp->nlen].phone = (char *)malloc(nlen + 1);
    59.         if (!(lp->pbuffer[lp->nlen].phone))
    60.         {
    61.                 free(lp->pbuffer[lp->nlen].name);
    62.                 return 0;
    63.         }
    64.         memset(lp->pbuffer[lp->nlen].phone, 0, nlen + 1);

    65.         /* 不是引用地址而是复制姓名和手机号,便于循环动态追加 */
    66.         strcpy(lp->pbuffer[lp->nlen].name, pdata->name);
    67.         strcpy(lp->pbuffer[lp->nlen].phone, pdata->phone);

    68.         lp->nlen++;
    69.         return lp->nlen;
    70. }

    71. /* 插入联系人 n=1,2,3,...*/
    72. int InsertList(List * lp, ElementType *pdata, int n)
    73. {
    74.         int i;
    75.         int nlen;
    76.         if (lp->nlen >= lp->nmax)
    77.         {
    78.                 printf("\nList is already full!\n");
    79.                 return 0;
    80.         }
    81.         if (n <= 0 || n > lp->nlen)
    82.         {
    83.                 printf("\nThe position to insert is out of List!\n");
    84.                 return 0;
    85.         }
    86.         for (i = lp->nlen; i >= n; i--)
    87.         {
    88.                 memcpy(&lp->pbuffer[i], &lp->pbuffer[i - 1], sizeof(ElementType));
    89.         }

    90.         /* memcpy(&lp->pbuffer[n - 1], pdata, sizeof(ElementType)); */
    91.         /* 每个联系人单独申请空间,这样联系人姓名和手机号就可以不限定长度了 */
    92.         nlen = strlen(pdata->name);
    93.         lp->pbuffer[n - 1].name = (char *)malloc(nlen + 1);
    94.         if (!(lp->pbuffer[n - 1].name))
    95.         {
    96.                 return 0;
    97.         }
    98.         memset(lp->pbuffer[n - 1].name, 0, nlen + 1);

    99.         nlen = strlen(pdata->phone);
    100.         lp->pbuffer[n - 1].phone = (char *)malloc(nlen + 1);
    101.         if (!(lp->pbuffer[n - 1].phone))
    102.         {
    103.                 free(lp->pbuffer[n - 1].name);
    104.                 return 0;
    105.         }
    106.         memset(lp->pbuffer[n - 1].phone, 0, nlen + 1);

    107.         /* 不是引用地址而是复制姓名和手机号,便于循环动态插入 */
    108.         strcpy(lp->pbuffer[n - 1].name, pdata->name);
    109.         strcpy(lp->pbuffer[n - 1].phone, pdata->phone);
    110.         lp->nlen++;

    111.         return lp->nlen;
    112. }

    113. /* 删除联系人  n=1,2,3,...*/
    114. int DeleteList(List * lp, int n)
    115. {
    116.         int i;
    117.         if (lp->nlen <= 0)
    118.         {
    119.                 printf("\nYou can't delete because List is Empty!\n");
    120.                 return 0;
    121.         }
    122.         if (n <= 0 || n > lp->nlen)
    123.         {
    124.                 printf("\nThe position to delete is out of List!\n");
    125.                 return 0;
    126.         }

    127.         /* 先释放该联系人占用的内存 */
    128.         if(lp->pbuffer[n-1].name) free(lp->pbuffer[n-1].name);
    129.         if(lp->pbuffer[n-1].phone) free(lp->pbuffer[n-1].phone);

    130.         /* 再将其后的联系人信息的指针逐个往前复制 */
    131.         for (i = n - 1; i < lp->nlen; i++)
    132.         {
    133.                 memcpy(&lp->pbuffer[i], &lp->pbuffer[i + 1], sizeof(ElementType));
    134.         }

    135.         /* 原末尾的联系人姓名、手机号处的指针清除 */
    136.         lp->pbuffer[lp->nlen].name = NULL;
    137.         lp->pbuffer[lp->nlen].phone = NULL;
    138.         /* memset(&lp->pbuffer[lp->nlen], 0, sizeof(ElementType)); */

    139.         lp->nlen--;
    140.         return lp->nlen;
    141. }

    142. /* 遍历联系人 */
    143. int TraverseList(List * lp, void (*f)(ElementType *pdata))
    144. {
    145.         int i;
    146.         if (lp->nlen == 0)
    147.         {
    148.                 printf("\nList is Empty!\n");
    149.                 return 0;
    150.         }
    151.         for (i = 0; i < lp->nlen; i++)
    152.         {
    153.                 f(&lp->pbuffer[i]);
    154.         }
    155.         printf("\n");
    156.         return 1;
    157. }

    158. /* 读取一条联系人记录  n=1,2,3,... */
    159. int GetElement(List * lp, ElementType *pdata, int n)
    160. {
    161.         if (n <= 0 || n > lp->nlen)
    162.         {
    163.                 printf("\nThe position to delete is out of List!\n");
    164.                 return 0;
    165.         }
    166.         memcpy(pdata, &lp->pbuffer[n-1], sizeof(ElementType));
    167.         return 1;
    168. }
    复制代码

    1. /* test3.c -- 通讯录文件                      */
    2. /* 和list3.c一起编译                          */
    3. /* 本通讯录的联系人姓名和手机号码串可任意长度 */

    4. #include "List3.h"

    5. void myprintf(ElementType * pdata)
    6. {
    7.         printf("{%s, %s}\n", pdata->name, pdata->phone);
    8. }

    9. int main()
    10. {
    11.         int i;
    12.         List *lp = InitList(9);
    13.         ElementType str[] = {
    14.                 {"AAAAAA","11111111111"},
    15.                 {"BBBBBB","22222222222"},
    16.                 {"CCCCCC","33333333333"},
    17.                 {"DDDDDD","44444444444"},
    18.                 {"EEEEEE","55555555555"},
    19.                 {"FFFFFF","66666666666"},
    20.                 {"GGGGGG","77777777777"},
    21.                 {"HHHHHH","88888888888"},
    22.                 {"IIIIII","99999999999"},
    23.         };
    24.         ElementType data = {"KKKKKK","12345678901"};
    25.         if(!lp)
    26.         {
    27.                 printf("\nInitList error!\n");
    28.                 return 0;
    29.         }
    30.         for (i = 0; i < 9; i++)
    31.         {
    32.                 AppendList(lp, str+i);
    33.         }
    34.         /* 以上改为运行时循环输入联系人信息。这里为简化示例才固定初始化信息 */


    35.         TraverseList(lp, myprintf);

    36.         /* 以下可改为菜单选择动态追加、插入、删除、检索、清除。*/

    37.         DeleteList(lp, 3);
    38.         TraverseList(lp, myprintf);

    39.         DeleteList(lp, 3);
    40.         TraverseList(lp, myprintf);

    41.         GetElement(lp, &data, 3);
    42.         myprintf(&data);
    43.         printf("\n");

    44.         AppendList(lp, &data);
    45.         TraverseList(lp, myprintf);

    46.         InsertList(lp, &data, 1);
    47.         TraverseList(lp, myprintf);

    48.         AppendList(lp, &data);
    49.         TraverseList(lp, myprintf);

    50.         DestroyList(lp);/* 用tc2编译的运行时这里提示 "Null pointer assignment" ,请找出错在哪里*/

    51.         return 1;
    52. }
    复制代码



    list3_src.rar

    2.4 KB, 下载次数: 0, 下载积分: 飘云币 -2 枚

    PYG19周年生日快乐!

    该用户从未签到

    发表于 2015-2-5 18:51:22 | 显示全部楼层
    学的好快呀~我才看到第7课~而且菱形代码还没有实现,正在努力思考ing~
    PYG19周年生日快乐!
    您需要登录后才可以回帖 登录 | 加入我们

    本版积分规则

    快速回复 返回顶部 返回列表