菜鸟如何快速理解实现通讯录——静态方法

       不是有一句话叫做学生给学生当老师,学生最容易听懂明白吗?没错,我这个菜鸟给你讲讲这个通讯录项目的实现,让你更能清楚明白其中的奥秘。

       这个代码没有经过过多的优化,只是为了代码能够让更多的人读懂,所以也不是最好的代码,你们可以理解了以后自己去做做优化。

      代码用的知识就是C语言中最基本的操作。

项目要求:

实现一个通讯录;

 

通讯录可以用来存储1000个人的信息,每个人的信息包括:

 

姓名、性别、年龄、电话、住址

提供方法:

 

1. 添加联系人信息

 

2. 删除指定联系人信息

 

3. 查找指定联系人信息

 

4. 修改指定联系人信息

 

5. 显示所有联系人信息

 

6. 清空所有联系人

 

7. 以名字排序所有联系人

 

代码实现:

AddRess.h

#ifndef __ADDRESS_H__
#define __ADDRESS_H__
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#define  MAX 10     //这里我为了调试方便取了一个较小的数值
enum OP
{
 EXIT = 0,//退出
 ADD,     //增加联系人
 DEL,     //删除联系人
 SEEK,    //查找联系人
 REVISE,  //修改联系人
 SHOW,    //显示所有联系人
 EMPTY,   //清空所有联系人
 SORT,    //以名字排序所有联系人
};
//姓名、性别、年龄、电话、住址
typedef struct PesonMessage
{
 char name[20];
 char sex[5];
 int age;
 char tel[15];
 char address[20];
}PesonMessage;
//通讯录成员结构体;
typedef struct Peson
{
 PesonMessage people[MAX];
 int size;
}Peson,*pPeson;
void Print_AddRess();
void Add_AddRess(pPeson peson);
void Show_AddRess(pPeson peson);
void Empty_AddRess(pPeson peson);
void Del_AddRess(pPeson peson);
void Seek_AddRess(pPeson peson);
void Revise_AddRess(pPeson peson);
void Sort_AddRess(pPeson peson);
void Cheak(pPeson peson);
#endif//__ADDRESS_H__

AddRess.c

#define _CRT_SECURE_NO_WARNINGS 1
#include "AddRess.h"
void Print_AddRess()
{
 printf("**************************\n");//输出的时候要保证屏幕上干净整齐
 printf("*****0.   退出系统   *****\n");//让别人有读下去的兴趣
 printf("*****1.添加联系人信息*****\n");
 printf("*****2.删除联系人信息*****\n");
 printf("*****3.查找联系人信息*****\n");
 printf("*****4.修改联系人信息*****\n");
 printf("*****5.显示联系人信息*****\n");
 printf("*****6.清空所有联系人*****\n");
 printf("*****7.名字排序联系人*****\n");
 printf("**************************\n");
}
void Add_AddRess(pPeson peson)
{
 assert(peson);//断言指针是否有效
 if(peson->size < MAX)//判断peson->size是否合法
 {
  //简单的输入输出
  printf("添加联系人信息\n");//姓名、性别、年龄、电话、住址
  printf("请输入联系人姓名:\n");
  scanf("%s",&(peson->people[peson->size].name));
  printf("请输入联系人的性别:\n");
  scanf("%s",&(peson->people[peson->size].sex));
  printf("请输入联系人的年龄:\n");
  scanf("%d",&(peson->people[peson->size].age)); 
  printf("请输入联系人的电话:\n");
  scanf("%s",&(peson->people[peson->size].tel));
  printf("请输入联系人的住址:\n");
  scanf("%s",&(peson->people[peson->size].address));
  peson->size++;//每次增加一个联系人,有效的size都要+1
 }
 else
 {
  printf("通讯录已满\n");//如果peson->size >= MAX
 }
}
void Show_AddRess(pPeson peson)
{
 int i = 0;
 assert(peson);//断言指针是否有效
 printf("%5s\t","name");//%Xs  的方式使字符串从最右边开始打印对齐  X可是是随意的值,这里的取了一个较小的数字
 printf("%5s\t","sex");
 printf("%5s\t","age");
 printf("%5s\t","tel");
 printf("%5s\t","address");
 printf("\n");
 for (i = 0;i <peson->size;i++)
 {
  printf("%5s\t",peson->people[i].name);
  printf("%5s\t",peson->people[i].sex);
  printf("%5d\t",peson->people[i].age);
  printf("%5s\t",peson->people[i].tel);
  printf("%5s\t",peson->people[i].address);
  printf("\n");
 }
}
void Empty_AddRess(pPeson peson)
{
 assert(peson);//断言指针是否有效
 peson->size = 0;
}
void Del_AddRess(pPeson peson)
{
 char name[20] = {0};
 int i = 0;
 assert(peson);//断言指针是否有效
 if (peson->size == 0)
 {
  printf("通讯录已空\n");
 }
 printf("请输入需要删除联系人的姓名");
 scanf("%s",&name);
 for (i = 0;i < peson->size; i++)
 {
  if (strcmp(name,peson->people[i].name) == 0)//判断输入的姓名和通讯录的姓名是否一致
  {
   for (;i < peson->size;i++)
   {
    peson->people[i] = peson->people[i + 1];//发现一致的名字后,从当前下标的后一个下标的所有有效值赋值给前一个
   }                                           //覆盖掉需要删除的值,注意这里不能从最后一个有效值开始往前赋值,会丢失数据的
   peson->size--;//每次删除一个数据,有效size要减掉一个
  } 
 }
 if (i == peson->size)
 {
  printf("对不起,找不到您所要删除的联系人\n");
 }
}
void Seek_AddRess(pPeson peson)
{
 char name[20] = {0};
 int i = 0;
 assert(peson);//断言指针是否有效
 if (peson->size == 0)
 {
  printf("通讯录已空\n");
 }
 printf("请输入需要查找联系人的姓名");
 scanf("%s",&name);
 for (i = 0;i < peson->size; i++)
 {
  if (strcmp(name,peson->people[i].name) == 0)
  {
   printf("%5s\t","name");
   printf("%5s\t","sex");
   printf("%5s\t","age");
   printf("%5s\t","tel");
   printf("%5s\t","address");
   printf("\n");
   printf("%5s\t",peson->people[i].name);
   printf("%5s\t",peson->people[i].sex);
   printf("%5d\t",peson->people[i].age);
   printf("%5s\t",peson->people[i].tel);
   printf("%5s\t",peson->people[i].address);
   printf("\n");
  } 
 }
}
void Revise_AddRess(pPeson peson)
{
 char name[20] = {0};
 char Char_Tmp[20] = {0};
 int Int_Tmp = 0;
 int i = 0;
 int num = 0;
 assert(peson);//断言指针是否有效
 if (peson->size == 0)
 {
  printf("通讯录已空\n");
 }
 printf("请输入需要修改的联系人的姓名");
 scanf("%s",&name);
 for (i = 0;i < peson->size; i++)
 {
  if (strcmp(name,peson->people[i].name) == 0)
  {
   printf("1.name\n");
   printf("2.sex\n");
   printf("3.age\n");
   printf("4.tel\n");
   printf("5.address\n");
   printf("请输入需要修改的对应序号:\n");
   scanf("%d",&num);
   switch (num)
   {
   case 1:
    printf("请输入联系人姓名\n");
    scanf("%s",&Char_Tmp);
    strcpy(peson->people[i].name,Char_Tmp);
    break;
   case 2:
    printf("请输入联系人性别\n");
    scanf("%s",&Char_Tmp);
    strcpy(peson->people[i].sex,Char_Tmp);
    break;
   case 3:
    printf("请输入联系人年龄\n");
    scanf("%d",&Int_Tmp);
    peson->people[i].age = Int_Tmp;
    break;
   case 4:
    printf("请输入联系人电话\n");
    scanf("%s",&Char_Tmp);
    strcpy(peson->people[i].tel,Char_Tmp);
    break;
   case 5:
    printf("请输入联系人住址\n");
    scanf("%s",&Char_Tmp);
    strcpy(peson->people[i].address,Char_Tmp);
    break;
   default:
    printf("对不起,输入错误\n");
    break;
   }
  } 
 }
}
void Sort_AddRess(pPeson peson)//冒泡排序
{
 char name[20] = {0};
 int i = 0;
 int j = 0;
 PesonMessage tmp;
 assert(peson);//断言指针是否有效
 if (peson->size == 0)
 {
  printf("通讯录已空\n");
 }
 for (i = 0; i < peson->size-1; i++)//排序的趟数
 {
  for (j = 0;j < peson->size - i - 1;j++)//比较的个数
  {
   if (strcmp(peson->people[j].name,peson->people[j + 1].name) < 0)
   {
    //strcpy(tmp,peson->people[j].name);    //刚开始欠缺考虑只是交换了两组姓名而已
    //strcpy(peson->people[j].name,peson->people[j + 1].name);
    //strcpy(peson->people[j + 1].name,tmp);
    tmp = peson->people[j];
    peson->people[j] = peson->people[j+1];
    peson->people[j+1] = tmp;
   }
  }
 }
}
void Cheak(pPeson peson)
{
 int index = 0;
 while(1)
 {
  Print_AddRess();
  printf("请选择:\n");
  scanf("%d",&index);
  switch(index)
  {
  case EXIT:
   exit(0);
   break;
  case ADD:
   Add_AddRess(peson);
   break;
  case DEL:
   Del_AddRess(peson);
   break;
  case SEEK:
   Seek_AddRess(peson);
   break;
  case REVISE:
   Revise_AddRess(peson);
   break;
  case SHOW:
   Show_AddRess(peson);
   break;
  case EMPTY:
   Empty_AddRess(peson);
   break;
  case SORT:
   Sort_AddRess(peson);
   break;
  default:
   printf("输入有误\n");
   break;
  }
 }
}

test.c

#define _CRT_SECURE_NO_WARNINGS 1

#include "AddRess.h"

int main()

{

 Peson peson;

 peson.size = 0;

 Cheak(&peson);

 system("pause");

 return 0;

}

时间: 2024-10-12 22:36:49

菜鸟如何快速理解实现通讯录——静态方法的相关文章

如何快速理解一个全新的嵌入式操作系统(续)

---基于TI CC254X OSAL的分析 当工具链配置完成后,SourceInsight向你展示一份源码工程,不借助百度和开发文档,能否在一两个小时内理解源码的组成框架和接口,进行快速开发? 上一篇<如何快速理解一个全新的嵌入式操作系统>我们已经分析了如何快速理解OSAL的任务调度和任务间通信(其实OSAL只是酷似多任务操作系统的单任务系统),再理解好OASL的消息产生和处理过程,我们就能够进行快速开发了. 一.消息的来源 嵌入式系统的消息包括两种,一是系统消息,包括低电.热插拔等,由系统

快速理解VirtualBox的四种网络连接方式

VirtualBox中有4中网络连接方式: NAT Bridged Adapter Internal Host-only Adapter VMWare中有三种,其实他跟VMWare 的网络连接方式都是一样概念,只是比VMWare多了Internal方式. 要让自己(或别人)理解深刻,方法就是做比较和打比方,比较之间的不同和相同,拿熟知的事物打比方.先来一张图,通过这张图就很容易看出这4种方式的区别: (注:此图直接取至Finalbug的Blog,表示感谢) 再来用文字做详细的解释(其实归结起来就

如何快速理解一个全新的嵌入式操作系统

---基于TI CC254X OSAL的分析 当工具链配置完成后,Source Insight向你展示一份源码工程,不借助百度和开发文档,能否在一两个小时内理解源码的组成框架和接口,进行快速开发? 在笔者过往撰写的博文中,一直在倡导两个嵌入式学习和开发理念:提高嵌入式系统架构和软件层次形成大局观:掌握从需求的角度去理解新系统和技术这个方法论.在软件大局观作为学习新系统的背景知识的基础上,从软件需求的角度入手就能快速理解和掌握一个全新的系统.本文以TI蓝牙BLE CC254x的源码库和工程为例进行

快速理解RxJava源码的设计理念

前言 我在看过几篇关于RxJava源码分析的博客后,不知是我的水平有限还是源码过于博大精深,导致花了很长的时间才搞清楚其运行原理.我个人觉得应该有更好的办法来快速剖析理解,于是决定写下本文. 本文适合已经看过一些RxJava源码分析资料的同学,不过没看过也没关系.在看本文时可参考这篇博客:RxJava基本流程和lift源码分析,它说得比较全,在此感谢博主大头鬼Bruce. 一.初探RxJava [以下摘录了RxJava基本流程和lift源码分析] 我们先来看一段最基本的代码,分析这段代码在RxJ

[转帖]十分钟快速理解DPI和PPI,不再傻傻分不清!

十分钟快速理解DPI和PPI,不再傻傻分不清! https://baijiahao.baidu.com/s?id=1605834796518990333&wfr=spider&for=pc关于UX测试相关的: 之前一直搞的不是很清楚 这个百家号的解释挺好的 简单转帖一下 以后仔细研究,  设计师充电站 18-07-1308:58 72DPI的图片拿去打印会糊吗?手机拍出来的照片是多少DPI?PS里显示72PPI为什么另存为JPG就变成96DPI了? 类似的问题层出不穷.本站很多篇文章都讲到

快速理解JavaScript语法

目录 导论 JavaScript的学习可以跳过哪些 console对象与控制台 console对象 console对象与方法 console.log() console.table() console.count() console.assert() JSON对象 JSON方法 JSON.stringify() JSON.parse() 异步与promise 回调函数 事件监听 Promise 对象 Promise 对象的状态 Promise 构造函数 Promise.prototype.the

扩展方法的快速理解

---恢复内容开始--- 今天记录一下自己对扩展方法的理解,扩展方法就是实现某种功能但是在原有的类或程序集中又不存在这种功能实现的方法或者封装,继而衍生出扩展方法.但是新建一个类来封装实现这种功能的方法也可以达到目的而且使用继承机制也可以实现,为何有衍生扩展方法呢? 第一种方式是比较通用的一种方式,也是通常情况下使用最多的,但和扩展方法比较来说,代码的可读性不如扩展方法. 继承的方式是一个很好的扩展方案,但有时不一定是完美的,比如:a. 每次继承都会产生新类,且使用时需要进行相应的强制转换(st

快速理解DevOps概念和意义-兼谈SRE

最近几年,由于负责的范围的变化.工作逐渐从某个IT领域或者部门,开始关注到整个IT体系的运转和管理.中间也遇到不少困难,同时也有机会去从更高的层面去学习和实践IT治理.文章主要是总结一下我对DevOps相关的理解和认识. 为什么会有DevOps,解决了什么问题: 现代企业其实都是通过IT系统进行管理和运营的,在变化迅速和竞争激烈的领域,IT系统的新需求数量越来越多,软件发布的频率越来越高,不少互联网公司24小时内会发布几十个到上百个release到生产环境.与此同时,业务对IT服务和系统的稳定性

快速理解C语言指针

新手在C语言的学习过程中遇到的最头疼的知识点应该就是指针了,指针在C语言中有非常大的用处.下面我就带着问题来写下我对于指针的一些理解. 指针是什么?  指针本身是一个变量,它存储的是数据在内存中的地址而不是数据本身的值.它的定义如下: int a=10,*p; p=&a int a=10; int *p=&a; 首先我们可以理解 int* 这个是要定义一个指针p,然后因为这个指针存储的是地址所以要对a取地址(&)将值赋给指针p,也就是说这个指针p指向a. 很多新手都会对这两种定义方