##一、通訊錄準備 #####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,則傳遞的是一個常量指針,此時使用的便是 箭頭操作符。