C語言實現通訊錄

来源:https://www.cnblogs.com/zzao/archive/2023/03/09/17191426.html
-Advertisement-
Play Games

##一、通訊錄準備 #####1. 通訊錄信息的準備 #####2. 通訊錄功能的框架 #####3. 文件安排 ##二、實現通訊錄的功能 #####1. 添加功能 #####2. 刪除功能 #####3. 展示功能 #####4. 更改功能 #####5. 查找功能 #####6. 排序功能 ## ...


一、通訊錄準備

1. 通訊錄信息的準備
2. 通訊錄功能的框架
3. 文件安排

二、實現通訊錄的功能

1. 添加功能
2. 刪除功能
3. 展示功能
4. 更改功能
5. 查找功能
6. 排序功能

三、總結

1.在main函數中,採用&的原因
2.在使用scanf函數時,為何某些參數不需要&,而有一些參數需要使用&
3.在添加功能中,傳遞的參數:ps->data[ps->size].xxxx 中,為什麼訪問xxxx時使用的是 點操作符,而不是 箭頭操作符

一、通訊錄的準備

1.通訊錄信息的準備

通訊錄中要有 人名、年齡、性別、地址、手機號碼這些信息,因此我們可以通過結構體進行實現。

我們在實現了通訊錄的基本信息後,我們需要對通訊錄的各個信息大小進行設置,以及通訊錄的長度等,並將功能進行聲明。

將以上要求寫入頭文件(contact.h)中

#include<stdio.h>
#include<string.h>
#define MAX_NAME 20
#define MAX_SEX 4
#define MAX_ADDR 20
#define MAX_TELE 12
#define MAX 1000
struct PeoInfo{
  char name[MAX_NAME];
  int age;
  char sex[MAX_SEX];
  char addr[MAX_ADDR];
  char tele[MAX_TELE];
}
struct Contact{
  struct PeoInfo data[MAX];
  int size;                //通訊錄的現有長度
}
//初始化通訊錄
void InitContact(struct Contact*ps);
//增加功能
void AddContact(struct Contact*ps);
//刪除功能
void DelContact(struct Contact*ps);
//更改功能
void ModifyContact(struct Contact*ps);
//查找功能
void SearchContact(const struct Contact*ps);    //此處使用const,是因為查找並不改變數據,展示也是同理
//展示功能
void ShowContact(const struct Contact*ps);
//排序功能
void SortContact(struct Contact*ps);
2.通訊錄功能的大致框架

通訊錄的功能中包含增刪改查,我們在此基礎上,增加了展示功能以及排序功能,以及使用之前需要初始化,其大致框架如下:寫入test.c中

#include"contact.h"
void menu(){
  printf("********************\n");
  printf("**1.增加    2.刪除***\n");
  printf("**3.更改    4.查找***\n");
  printf("**5.展示    6.搜索***\n");
  printf("**0.退出         ***\n");
  printf("********************\n");
  
}
int main(){
  int input=0;
  struct Contact con;     //創建通訊錄
  InitContact(&con);      //初始化通訊錄

  do{
    menu();
    printf("輸入您的選擇:>");
    scanf("%d",&input);
    switch(input){
    case ADD:
        AddContact(&con);           //增加功能      與枚舉中的ADD對應   1
    case DEL:
        DelContact(&con);           //刪除功能      與枚舉中的DEL對應   2
    case MODIFY:
        ModifyContact(&con);        //更改功能
    case SEARCH:
        SearchContact(&con);        //搜索功能
    case SHOW:
        ShowContact(&con);          //展示功能
    case SORT:
        SortContact(&con);          //排序功能
    case EXIT:                                  // 與枚舉中的EXIT對應  0
        printf("退出\n");
    default:
        printf("請輸入0——6範圍內的數字\n");
    
  }

    }while(input);

}

上述代碼中的switch選項 是通過頭文件中的枚舉進行實現的,寫入contact.h中,代碼如下

 enum Option
 {  
   EXIT,              //此處採用枚舉進行一個switch的選項,枚舉中
   ADD,               //首項預設為0,然後依次加1,最終各項正好與switch()中的選項值相等
   DEL,               //於是當輸入0~6時,對應test.c中的功能
   MODIFY,
   SEARCH,
   SHOW,
   SORT
 }            
3.文件安排

我們使用三個文件進行通訊錄的實現:
1.test.c
2.contact.h
3.contact.c
我們將main函數放在test.c文件中,而通訊錄信息等數據結構,預處理,聲明等放在contact.h文件中,而具體功能放置在contact.c文件中

初始化代碼如下(寫入contact.c中):

void InitContact(struct Contact*ps){
  memset(ps->data,0,sizeof(ps->data));
  ps->size=0;
}

二、通訊錄功能的實現

1.添加功能
void AddContact(struct Contact*ps){
      if(ps->size==MAX)
{    printf("已滿,無法添加\n");  
}
     else
{
  printf("請輸入添加的人名:>");
  scanf("%s",ps->data[ps->size].name);        //data作為數組名時,代表的是指針,當我們要其內部成員時,需要使用箭頭操作符
  printf("請輸入添加的年齡:>");                 //但當以數組形式時,data[i],這種形式時
  scanf("%d",&(ps->data[ps->size].age));    //此時是一個命名的具體的單個結構體,於是我們用
  printf("請輸入添加的性別:>");                //點操作符直接訪問其內部成員,而不是箭頭操作符
  scanf("%s",ps->data[ps->size].sex);  
  printf("請輸入添加的地址:>");
  scanf("%s",ps->data[ps->size].addr);  
  printf("請輸入添加的電話:>");
  scanf("%s",ps->data[ps->size].tele);  
  
  ps->size++;
}
}
2.刪除功能
void FindByNmae(struct Contact*ps)
{  
  char name[MAX_NAME];
  printf("輸入查找的名字:>");
  scanf("%s",&name);
  int i=0;
  for(i=0;i<ps->size;i++)
    {  if(0==strcmp(name,ps->data[i].name)
            return i;)
        }
   return -1;
}
void DelContact(struct Contact*ps)
{
  //查找功能
  int pos=FindByName(ps);
  //刪除功能
  if(pos==-1)
  {printf("沒有此人\n");
  }
  else
{  int j=0;  
   for(j=pos;j<ps->size-1;j++)
    {
        ps->data[ret].name=ps->data[ret+1].name; 
          }
    ps->size--;
    printf("刪除成功\n");
}

}
3.更改功能
void ModifyContact(struct Contact*ps)
{
  int pos=FindByName(ps);
  if(pos==-1)
    {
      printf("查無此人\n");  
      }
  else
  {
  printf("請輸入更改的人名:>");
  scanf("%s",ps->data[pos].name);  
  printf("請輸入更改的年齡:>");
  scanf("%d",&(ps->data[pos].name));  
  printf("請輸入更改的性別:>");
  scanf("%s",ps->data[pos].sex);  
  printf("請輸入更改的地址:>");
  scanf("%s",ps->data[pos].addr);  
  printf("請輸入更改的電話:>");
  scanf("%s",ps->data[pos].tele);  
  }

}
4.查找功能
void SearchContact(const struct Contact*ps)
{
  int pos=FindByName(ps);
  if(pos==-1)
  {
    printf("查無此人\n");
}
  else
{
  printf("%20s\t%4s\t%10s\t%12s\t%20s\t","姓名","年齡","性別","地址","電話");
  printf("%20s\t%4d\t%10s\t%12s\t%20s\t",
      ps->data[pos].name,
      ps->data[pos].age,
      ps->data[pos].sex,
      ps->data[pos].addr,
      ps->data[pos].tele);
}
}
5.展示功能
void ShowContact(const struct Contact *ps)
{
  if(ps->size==0)
  {
      printf("列表為空\n");
}
  else
  {
    printf("%20s\t%4s\t%10s\t%12s\t%20s\t","姓名","年齡","性別","地址","電話");
    int i=0;  
    for(i=0;i<ps->size;i++)
      {      
      printf("%20s\t%4d\t%10s\t%12s\t%20s\t",
      ps->data[i].name,
      ps->data[i].age,          //此處age為%d,是因為age在結構體中為int型
      ps->data[i].sex,
      ps->data[i].addr,
      ps->data[i].tele);
}
}    
}
6.排序功能
void bubble_sort(struct Contact*ps)
{
  int i=0;
  for(i=0;i<ps->size;i++)
  {
      int j=0;
      for(j=0;j<ps->size-1-i;j++)
    {
        if(ps->data[j].age>ps->data[j+1].age)
      {
          struct PeoInfo tmp=ps->data[j];
          ps->data[j]=ps->data[j+1];
          ps->data[j+1]=tmp;
    }            
}
}
}
void SortContact(const struct Contact*ps)
{
  bubble_sort(ps);
  printf("排序成功\n");        //該功能是通過年齡進行排序的
}

三、總結

1.在main函數中,採用&的原因

因此此時我們在main函數中創建了con,此時的con只是一個結構體,因此當我們需要進行操作時,我們需要取其地址,再進行操作,於
是傳遞的參數便是 &con

2.在使用scanf函數時,為何某些參數不需要&,而有一些參數需要使用&

在增加功能中,我們可以看到scanf中,有些參數傳遞時需要 &符號,而有些不需要,是因為類型不同,name,sex,addr,tele等參數在
struct PeoInfo中是數組,數組名在使用時會產生 指針常量,指向第一個元素地址,因此不需要,而age需要&符號,是因為此時age是
int類型,需要傳遞其地址,才能修改其值。

3.在添加功能中,傳遞的參數:ps->data[ps->size].xxxx 中,為什麼訪問xxxx時使用的是 點操作符,而不是 箭頭操作符

因為此時data[ps->size],此時的data是一個命名的單個的結構體,而不是指針,因此在訪問其成員時,使用的是點頭操作符。
若此時只有數組名data,則傳遞的是一個常量指針,此時使用的便是 箭頭操作符。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Webix是Javascript庫 一種軟體產品 用於加速Web開發的 JavaScript UI庫和框架 Webix用於跨平臺 Web應用程式開發的JS框架 102個UI小部件和 功能豐富的CSS/HTML5 JavaScript控制項 開發商介紹 Webix團隊由由熱衷於創建高質量網路產品的專業人 ...
  • 前端路由的設置: Vue2路由(vue-router3) 安裝插件 npm i vue-router@3 router/index.js文件設置 import Vue from "vue"; import VueRouter from "vue-router"; Vue.use(VueRouter) ...
  • JavaScript中的發佈/訂閱模式(Pub/Sub)是一種常用的設計模式。它允許在應用程式中定義對象之間的一對多的依賴關係,當一個對象的狀態發生變化時,所有依賴於它的對象都會被通知和更新。 在發佈/訂閱模式中,有兩種類型的對象:發佈者和訂閱者。發佈者是事件的發出者,它通常維護一個事件列表,並且可 ...
  • 在各種場景的開發中Dialog組件的出現頻率都是非常高的,Dialog組件作為一個容器組件受容器內業務代碼複雜度的影響,代碼行數、變數及函數的定義可能會很多,這樣的組件就一定要考慮封裝使用,以保證主流程代碼的簡潔。下麵一起來看一下如何利用面向對象的思想來封裝它吧~ ...
  • w3c機構:規定網頁分成三個部分:結構、樣式、表現形式。 無序列表: (每個列表左側都有實心黑點,可以用css去掉) <ul> <li>列表1</li> <li>列表2</li> </ul> 快捷方式:ul>li*數量 tab <ul></ul>中只能嵌套<li></li> <li></li>之間相 ...
  • 這篇文章主要描述如何在使用消息隊列時避免丟消息,包括檢測消息丟失的方法以及消息從生產到完成消費的過程中,經歷的生產、存儲和消費這三個階段是分別如何保證消息可靠傳遞的。 ...
  • 一、文件系統存儲 電腦剛開始出現的時候,那時候沒有硬碟,只有記憶體,數據不會進行存儲,一般只用於科技計算,計算完輸出結果後,程式就撤出記憶體了。後來隨著技術發展,有了硬碟、文件,在文件的基礎上有了文件系統。文件系統可以滿足數據存放和查找的需求。 文件系統作為資料庫用了一段時間,當數據越來越多、規模越來 ...
  • 這篇文章描述如何使用消息隊列中的事務消息機制實現分散式事務。事務消息適用於需要非同步更新數據,並且對數據實時性要求不太高的場景。 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...