程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C >> C語言基礎知識 >> 留言簿程序的編寫

留言簿程序的編寫

編輯:C語言基礎知識

  
  1、構造留言簿的結構
      一個留言必不可少的是內容、其次是留言的日期和時間。和們就按這兩點定義留言記錄的結構。
  strUCt record
  {
      struct date t_date;        /*留言日期*/
      struct time t_time;        /*留言時間*/
      char event[100];           /*留言內容*/
      struct record *next;       /*指向下一個節點的指針*/
  };
  在上結構的定義中,用字符串event[100]存放留言內容,結構成員t_date存放留言的日期,t_time存放留言的時間。結構data和time的定義是Turbo C提供的。它們的定義分別如下所示:
  struct date
  {
      int da_year;
      char da_day;
      char da_mon;
  };
  struct time
  {
      unsigned char ti_min;
      unsigned char ti_hour;
      unsigned char ti_hund;
      unsigned char ti_sec;
  };
  2、入隊操作
      入隊操作比較簡單,只要能找到隊列的最後一個節點(即尾節點)修改尾節點的指針域,讓其指針指向新增加的節點即可。於是問題的要害就在於如何找到尾節點,或是找到尾節點的指針域。
      這裡采用設置頭節點和尾指針的方法來完成入隊操作。
      隊列在還沒有任何一條記錄時稱為隊空。此時我們在隊列中設置一個不存放任何記錄的節點,稱為“頭節點”(采用頭節點的好處在以後會體現出來),由於並無記錄,我們設置的指向隊尾的尾指針也指向這個頭節點。
      一旦需要添加記錄,就讓尾指針指向新節點(稱為節點1),而後把節點1的指針域賦給尾指針。由於尾指針為頭節點的指針域,這樣含頭節點就鏈接了節點1,即頭節點的指針指向節點1,形成了鏈的初始模型。當增加第二個節點(稱為節點2)時,仍然修改尾指針,讓其指向節點2,而後把節點2的指針域賦給尾指針。由於原來尾指針為節點1的指針域,因此節點1和節點2又鏈接在一起。現在的隊列由頭節點、節點1和節點2相互鏈接而成。依此類推,鏈隊就通過修改尾指針的值形成了。
      入隊操作的基本算法如下所示:
  void queue_add(struct element *rear,struct element *p)
  {
      p->next=NULL;
      rear->next=p;
      rear=p;
  }
      其中rear即為尾指針,而指針p指向新增的節點。算法的流程和上述完全一樣。
  錄入留言記錄的函數代碼如下所示:
  void Data_Input(struct record *p)
  {
      struct data *d;
      struct time *t;
      front++;
      getdate(t);        /*取系統時間*/
      p->t_time.ti_hour=ti_hour;
      p->t_time.ti_min=ti_min;
      p->time.ti_sec=ti_sec;
      printf(" Date:%4d %2d %2d",p->t_date.da_year,p->t_date.da_mon,p->t_date.da_day);
      printf(" Time: %2d: %2d: %2d",p->t_time.ti_hour,p->t_time.ti_min,p->t_time.ti_sec);
      printf(" Please input record:");
      gets(p->event);      /*輸入留言內容*/
      p->next=NULL;
  }
      上述函數中,采用了getdate()和gettime()兩個函數用來獲取系統的日期和時間。這兩個函數只返回指向當前日期和時間的兩個指針,還需要將值立即賦給留言記錄中的結構成員。
  3、出隊操作---留言記錄的刪除
      和入隊操作相反的是出隊操作,即在隊頭將記錄刪除,這也是符合“先進先出”的原則的。
      由於設置了頭節點,因此出隊操作顯得非常簡單。只需要修改頭節點的指針域,讓其指向第二個節點即可。而第一個節點則將其釋放掉。其余節點,包括尾指針都不必做任何修改操作。
      例如一個隊列原本由頭節點、節點1和節點2相鏈而成,執行出隊操作時,相當於將頭節點和節點1、節點1和節點2之間的兩條鏈斷開,而用斷鏈將頭節點和節點2鏈上,多出來的節點1將其釋放掉。
      典型的出隊操作算法如下:
  void queue_delete(struct element head)
  {
      struct element *temp;
      temp=head.next->next;
      head.next=temp;
  }
      在執行出隊操作時,一定要記住需要將出隊的節點釋放。由於采用鏈式存儲,事先無法估計需要多大的存銷售市場空間,也不必去估計。每次新增一個節點時,都是調用內存分配函數為新節點申請一塊內存,如下所示:
      p=malloc(sizeof(struct record)
       函數malloc開辟了一塊大小為record 結構元素的內存區域,把掻向該區域的指針賦給指針p,這塊內存單元的所有權就從系統轉移到了指針p。當p指向的數據元素被刪除(出隊)時,一定要用如下方式將內存單 所有權還給系統:
      free(p);
      函數free()的作用和malloc()剛好相反,它將指定的內存單元還給了系統。因為系統的內存單元是有限的,假如不及時釋放占用的內存,會造成內存資源耗盡或由於內存的減少導致程序執行速度下降。
  4、記錄的存取的讀取
  void Data_Save(struct record *p)      /*記錄文件的存取*/
  {
      int j;
      fp=fopen(tele_rec.txt","w");      /*以可寫方式打開記錄文件*/
      while(p!=NULL)        /*若未到隊尾,徨將記錄存儲到文件中*/
      {
          fwrite(p.sizeof(struct record),1,fp);
          p=p->next;
      }
      fclose(fp);        /*關閉指定的文件*/
  }
  struct event *Data_Load()        /*從記錄文件中讀取記錄*/
  {
      long k;
      struct record *p,*q;
      p=event_head.next;
      fp=fopen("tele_rec.txt","r+t");        /*以讀方式打開記錄文件*/
      if(fp!=NULL)
      {
          while(!feof(fp))        /*依次讀取記錄並執行入隊操作*/
          {
              fread(q,sizeof(struct record),1,fp);
              p->next=q;        /*這裡p為尾指針,q為指向新節點的指針*/
              p=q;
          }
          p->next=NULL;
          event_end=p;
      }
      else
      {
          fp=fopen("tele_rec.txt","w");    /*若文件不存在,創建指定文件名的新文件*/
          event_head.next=NULL;
          event_end=event_head.next;
      }
  }
  
  
  /*-------------留言簿代碼如下-------------*/
  #include<stdio.h>
  #include<conio.h>
  #include<dos.h>
  struct record
  {
      struct date t_date;        /*定義留言日期*/
      struct time t_time;        /*定義留言時間*/
      char event[100];           /*定義電話內容*/
      struct record *next;       /*指向下一個節點的指針*/
  }event_head;
  
  struct record *event_end;
  int front;
  FILE *fp;
  
  void Data_Save(struct record *p)        /*記錄文件的存儲*/
  {
      int j;
      fp=fopen("tele_rec.txt","w");       /*以可寫方式打開記錄文件*/
      while(p!=NULL)  
  
 
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved