C语言实现通讯录

一、通讯录准备

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,则传递的是一个常量指针,此时使用的便是 箭头操作符。

原文链接:https://www.cnblogs.com/zzao/p/17191426.html

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C语言实现通讯录 - Python技术站

(0)
上一篇 2023年4月18日
下一篇 2023年4月18日

相关文章

  • python json.dumps() json.dump()的区别详解

    当我们需要将Python对象转换为JSON字符串时,我们可以使用Python内置的json模块。在使用json模块时,json.dumps()和json.dump()是两个常用的方法。它们之间有明显的区别,请看下文详解。 json.dumps() json.dumps()方法用来将Python对象转换为JSON格式的字符串,并返回生成的字符串,该方法的语法如…

    C 2023年5月23日
    00
  • C语言教程之数组详解

    C语言教程之数组详解 数组概述 数组是一组相同类型数据的集合,它们按照一定的先后顺序排列,每个数组元素可以通过一个下标访问。 在C语言中,数组元素是按照线性顺序存储在内存中的,数组下标从0开始,可以是整数、字符、枚举类型。 声明数组 在C语言中,可以使用以下方式来声明数组: type arrayName[arraySize]; 其中type为数组元素类型,a…

    C 2023年5月23日
    00
  • C++游戏教程基本技巧之随机化详解

    《C++游戏教程基本技巧之随机化详解》是一篇针对C++游戏开发者的教程,旨在讲解如何使用随机数来增加游戏的趣味性和难度。该教程主要包含以下几个方面的内容: C++随机数生成器的介绍 随机数应用在游戏中的场景 随机数生成的技巧和注意事项 随机数实现的两个示例 C++随机数生成器的介绍 C++的标准库中提供了一个随机数生成器库,名为rand()。该函数可以生成一…

    C 2023年5月22日
    00
  • JavaScript对象拷贝与Object.assign用法实例分析

    JavaScript对象拷贝与Object.assign用法实例分析 在JavaScript编程中,对象拷贝是一项非常重要的任务,因为我们经常需要在代码中使用对象,但由于JavaScript对象的引用特性,往往原始对象会被误修改或者无意间影响其他部分代码,这时候需要做对象拷贝,保持数据的安全完整性。JavaScript的标准库提供了多种深复制或浅复制对象的拷…

    C 2023年5月22日
    00
  • 手机版CCleaner怎么卸载软件应用程序

    下面是详细讲解“手机版CCleaner怎么卸载软件应用程序”的完整攻略: CCleaner简介 CCleaner是一款著名的系统清理与优化软件,其拥有较高的用户口碑。除去PC版本之外,CCleaner还在移动端推出了相应清理软件,广受用户好评。CCleaner安装在手机上后,它可以帮助用户管理手机存储空间,清理垃圾数据,优化手机性能。但有时,当用户不再需要某…

    C 2023年5月23日
    00
  • C语言中的编码小技巧

    当我们使用C语言编写代码时,有一些小技巧可以帮助我们写出更优美、更高效、更易于维护的代码。 1. 使用位运算来进行数值操作 在C语言中,位运算符(&、|、^、~、<<、>>)用于在二进制位级别上进行操作。这些运算符可以非常快速地执行某些数值计算,比如: 判断一个数是否是奇数或偶数:使用&运算符,如果一个数的最后一位是0…

    C 2023年5月23日
    00
  • C++多线程编程详解

    我会详细讲解C++多线程编程的攻略。对于多线程编程,一般分为以下几个步骤: 1. 包含头文件 要进行多线程编程,需要包含头文件<thread>。 #include <thread> 2. 创建线程 使用std::thread类创建一个线程,并将需要执行的函数作为参数传入。 void my_func() { // 线程要执行的代码 } …

    C 2023年5月22日
    00
  • C++深入探究继承的概念与使用

    C++深入探究继承的概念与使用 什么是继承? 继承是面向对象编程中的一个核心概念,它提供了一种在已有类的基础上构建新类的方式。继承是指子类从父类中继承成员变量和成员函数,并且可以在此基础上扩展出自己独有的属性和行为。继承有三种类型:公有继承、私有继承和保护继承。 公有继承 公有继承指的是子类从父类中继承了父类的公有成员和保护成员,并把这些成员都变成了子类的公…

    C 2023年5月23日
    00
合作推广
合作推广
分享本页
返回顶部