C语言-自定义类型-结构体应用-通讯录(11.2)

简介: C语言-自定义类型-结构体应用-通讯录(11.2)

1.通讯录的设计思路

我们创建三个文件拆分通讯录的实现过程:


一个测试文件(test.c)通讯录实现文件(contact.c)头文件(contact.h)



我们先对测试文件进行编辑,


写出一个总体的通讯录的框架。


1.1主函数与通讯录框架

在test.c文件中实现。


添加主函数:


int main()//主函数里不要放太多东西

{
  test();
  return 0;
}

分装test函数实现:


利用do...while循环:


void test()
{
  int input = 0;
   //初始化通讯录
  do
  {
  menu();//打印菜单
  printf("请选择:>");
  scanf("%d", &input);//选择功能
  switch(input)
  {
  case 1:
            //增加联系人
    break;
  case 2:
            //删除联系人
    break;
  case 3:
            //查找联系人
    break;
  case 4:
            //修改指定联系人
            break;
  case 5:
            //整理通讯录(按类型排序)
    break;
  case 6:
            //显示通讯录的信息
    break;
  case 0:
            //退出通讯录
    printf("通讯录已退出\n");
    break;
  default:
    printf("选择错误\n");
    break;
  }
  } while (input);
}


swich语句分出我们需要实现的功能。


1.2菜单的实现

打印菜单(可以按照自己的喜好设计):


void menu()
{
  printf("\n");
  printf("—————————— 通讯录 ———————————-\n");
  printf("—————————————————————————-\n");
  printf("————————   1.添加联系人    ————————\n");
  printf("—————————————————————————-\n");
  printf("————————   2.删除联系人    ————————\n");
  printf("—————————————————————————-\n");
  printf("————————   3.查找联系人    ————————\n");
  printf("—————————————————————————-\n");
  printf("————————   4.修改联系人信息  ———————\n");
  printf("—————————————————————————-\n");
  printf("————————   5.整理通讯录    ————————\n");
  printf("—————————————————————————-\n");
  printf("————————   6.查看整个通讯录  ———————\n");
  printf("—————————————————————————-\n");
  printf("————————   0.退出通讯录    ————————\n");
  printf("—————————————————————————-\n");
  printf("\n");
}


1.3通讯录的定义与初始化

基本框架设计好后,我们需要一段空间来存储通讯录中的数据:


在contact.h文件中实现:


#pragma once//防止头文件重复引用
//提前将需要使用的头文件引用,
//具体实现通讯录是,需要头文件可以直接添加
#include 
#include 
#include 
#include 
//通过#define定义的常量,方便管理和使用
#define MAX 100
#define NAME_MAX 20
#define SEX_MAX 5
#define ADDR_MAX 30
#define TELE_MAX 12
//通讯录中存放一个人的信息
typedef struct PeoInfo//typedef简化结构体名称
{
  char name[NAME_MAX];
  int age;
  char sex[SEX_MAX];
  char addr[ADDR_MAX];
  char tele[TELE_MAX];
}PeoInfo;
//创建一个结构体将数组和数组中存放的元素数封装
typedef struct Contact
{
  PeoInfo data[MAX];//data这个数组元素的类型的是结构体PeoInfo
                   //用来存放联系人信息
  int sz;//用来存放数组元素个数
}Contact;

这样,存放通讯录的结构体就创建完了,


接下来是通讯录的初始化:


在test.c文件中实现:


void test()
{
  int input = 0;
  //创建通讯录con
  Contact con;
    //初始化通讯录
    InitContact(&con);//分装成函数实现
  do
  {
  menu();//打印菜单
  printf("请选择:>");
  scanf("%d", &input);//选择功能
  switch(input)
  {
  case 1:
            //增加联系人
    break;
  case 2:
            //删除联系人
    break;
  case 3:
            //查找联系人
    break;
  case 4:
            //修改指定联系人
            break;
  case 5:
            //整理通讯录(按类型排序)
    break;
  case 6:
            //显示通讯录的信息
    break;
  case 0:
            //退出通讯录
    printf("通讯录已退出\n");
    break;
  default:
    printf("选择错误\n");
    break;
  }
  } while (input);
}

我们会将功能不断添加到test函数里面。


初始化通讯录的实现:


contact.h中声明函数,其他两个文件包含#include "contact.h"


//初始化通讯录
void InitContact(Contact* pc);
在contact.c文件中实现函数功能:
//初始化通讯录
void InitContact(Contact* pc)
{
  pc->sz = 0;//代表数组中有0个元素
  memset(pc->data, 0, sizeof(pc->data));//data是整个数组的大小,初始化成0

}

完成初始化后,我们就要具体实现通讯录的各种功能了。


2.通讯录具体功能的实现

2.1添加联系人

我们分装函数AddContact实现:


void test()
{
  int input = 0;
  //创建通讯录con
  Contact con;
    //初始化通讯录
    InitContact(&con);//分装成函数实现
  do
  {
  menu();//打印菜单
  printf("请选择:>");
  scanf("%d", &input);//选择功能
  switch(input)
  {
  case 1:
            //增加联系人
            AddContact(&con);
    break;
  case 2:
            //删除联系人
    break;
  case 3:
            //查找联系人
    break;
  case 4:
            //修改指定联系人
            break;
  case 5:
            //整理通讯录(按类型排序)
    break;
  case 6:
            //显示通讯录的信息
    break;
  case 0:
            //退出通讯录
    printf("通讯录已退出\n");
    break;
  default:
    printf("选择错误\n");
    break;
  }
  } while (input);
}


在contact.h中声明:


//初始化通讯录
void InitContact(Contact* pc);
//增加联系人
void AddContact(Contact* pc);
在contact.c文件中实现函数功能:
//增加联系人
void AddContact(Contact* pc/)
{
  assert(pc);
  if (pc->sz == MAX)//如果通讯录满了
  {
  printf("通讯录已满,无法添加\n");
  return;//就会直接返回
  }
  //增加一个人的信息
  printf("请输入名字:>");
  scanf("%s", pc->data[pc->sz].name);
  //通过pc指针访问data数组的结构体类型的元素,进而访问结构体成员
  printf("请输入年龄:>");
  scanf("%d", &(pc->data[pc->sz].age));//age不是数组,需要取地址
  printf("请输入性别:>");
  scanf("%s", pc->data[pc->sz].sex);
  printf("请输入地址:>");
  scanf("%s", pc->data[pc->sz].addr);
  printf("请输入电话:>");
  scanf("%s", pc->data[pc->sz].tele);
  pc->sz++;//代表数组中的元素个数+1
}

2.2删除联系人

我们分装函数DelContact实现:


void test()
{
  int input = 0;
  //创建通讯录con
  Contact con;
    //初始化通讯录
    InitContact(&con);//分装成函数实现
  do
  {
  menu();//打印菜单
  printf("请选择:>");
  scanf("%d", &input);//选择功能
  switch(input)
  {
  case 1:
            //增加联系人
            AddContact(&con);
    break;
  case 2:
            //删除联系人
            DelContact(&con);
    break;
  case 3:
            //查找联系人
    break;
  case 4:
            //修改指定联系人
            break;
  case 5:
            //整理通讯录(按类型排序)
    break;
  case 6:
            //显示通讯录的信息
    break;
  case 0:
            //退出通讯录
    printf("通讯录已退出\n");
    break;
  default:
    printf("选择错误\n");
    break;
  }
  } while (input);
}


在contact.h中声明:


//初始化通讯录
void InitContact(Contact* pc);
//增加联系人
void AddContact(Contact* pc);
//删除联系人
void DelContact(Contact* pc);
在contact.c文件中实现函数功能:
//查找函数
int FindByName(const Contact* pc, char name[])
{
  int i = 0;
  int del = 0;
  for (i = 0; i < pc->sz; i++)//遍历通讯录
  {
  if (strcmp(pc->data[i].name, name) == 0)
  {   //通过strcmp函数判断要查找的联系人是否存在
    del = i;
    return del;//返回数组下标(要查找的元素的位置)
  }
  }
  return -1;//找不到
}
//删除联系人
void DelContact(Contact* pc)
{
  assert(pc);
  char name[NAME_MAX] = { 0 };//初始化name数组(字符串)
  if (pc->sz == 0)//判断通讯录中是否存在联系人
  {
  printf("通讯录为空,无法删除\n");
  return;
  }
  //找到要删除的人
  printf("请输入要删除的人的名字:>");
  scanf("%s", name);//输入字符串
  int ret = FindByName(pc, name);//分装字符串查找函数
  if (-1 == ret)
  {
  printf("要删除的人不存在\n");
  return;
  }
  //删除
  int i = 0;
  for (i = ret; i < pc->sz - 1; i++)
  {
  pc->data[i] = pc->data[i + 1];//将存放在被删除的联系人后面的联系人信息,
    }                                 //通过循环一个个往前覆盖
  pc->sz--;//数组元素-1
  printf("删除成功\n");
}


2.3查找联系人

我们分装函数SearchContact实现:


void test()
{
  int input = 0;
  //创建通讯录con
  Contact con;
    //初始化通讯录
    InitContact(&con);//分装成函数实现
  do
  {
  menu();//打印菜单
  printf("请选择:>");
  scanf("%d", &input);//选择功能
  switch(input)
  {
  case 1:
            //增加联系人
            AddContact(&con);
    break;
  case 2:
            //删除联系人
            DelContact(&con);
    break;
  case 3:
            //查找联系人
            SearchContact(&con);
    break;
  case 4:
            //修改指定联系人
            break;
  case 5:
            //整理通讯录(按类型排序)
    break;
  case 6:
            //显示通讯录的信息
    break;
  case 0:
            //退出通讯录
    printf("通讯录已退出\n");
    break;
  default:
    printf("选择错误\n");
    break;
  }
  } while (input);
}
在contact.h中声明:
//初始化通讯录
void InitContact(Contact* pc);
//增加联系人
void AddContact(Contact* pc);
//删除联系人
void DelContact(Contact* pc);
//查找联系人
void SearchContact(const Contact* pc);
在contact.c文件中实现函数功能:
//查找函数
int FindByName(const Contact* pc, char name[])
{
  int i = 0;
  int del = 0;
  for (i = 0; i < pc->sz; i++)//遍历通讯录
  {
  if (strcmp(pc->data[i].name, name) == 0)
  {   //通过strcmp函数判断要查找的联系人是否存在
    del = i;
    return del;//返回数组下标(要查找的元素的位置)
  }
  }
  return -1;//找不到
}
//查找联系人
void SearchContact(const Contact* pc)
{
  assert(pc);
  char name[NAME_MAX] = { 0 };//初始化name数组(字符串)
  printf("请输入要查找人的名字:>");
  scanf("%s", name);
  int pos = FindByName(pc, name);//函数复用
  if (-1 == pos)
  {
  printf("要查找的人不存在\n");
  return;
  }
  //打印信息//我实现的是左对齐,并用水平制表符使打印出来的观感更好
  printf("%-10s\t%-4s\t%-5s\t%-20s\t%-12s\n", "名字", "年龄", "性别", "地址", "电话");
  printf("%-10s\t%-4d\t%-5s\t%-20s\t%-12s\n",
    pc->data[pos].name,
    pc->data[pos].age,
    pc->data[pos].sex,
    pc->data[pos].addr,
    pc->data[pos].tele);
}


2.4修改联系人信息

我们分装函数ModefyContact实现:

void test()
{
  int input = 0;
  //创建通讯录con
  Contact con;
    //初始化通讯录
    InitContact(&con);//分装成函数实现
  do
  {
  menu();//打印菜单
  printf("请选择:>");
  scanf("%d", &input);//选择功能
  switch(input)
  {
  case 1:
            //增加联系人
            AddContact(&con);
    break;
  case 2:
            //删除联系人
            DelContact(&con);
    break;
  case 3:
            //查找联系人
            SearchContact(&con);
    break;
  case 4:
            //修改指定联系人
            ModifyContact(&con);
            break;
  case 5:
            //整理通讯录(按类型排序)
    break;
  case 6:
            //显示通讯录的信息
    break;
  case 0:
            //退出通讯录
    printf("通讯录已退出\n");
    break;
  default:
    printf("选择错误\n");
    break;
  }
  } while (input);
}


在contact.h中声明:


//初始化通讯录
void InitContact(Contact* pc);
//增加联系人
void AddContact(Contact* pc);
//删除联系人
void DelContact(Contact* pc);
//查找联系人
void SearchContact(const Contact* pc);
//修改指定联系人
void ModifyContact(Contact* pc);
在contact.c文件中实现函数功能:
//查找函数
int FindByName(const Contact* pc, char name[])
{
  int i = 0;
  int del = 0;
  for (i = 0; i < pc->sz; i++)//遍历通讯录
  {
  if (strcmp(pc->data[i].name, name) == 0)
  {   //通过strcmp函数判断要查找的联系人是否存在
    del = i;
    return del;//返回数组下标(要查找的元素的位置)
  }
  }
  return -1;//找不到
}
//修改指定联系人
void ModifyContact(Contact* pc)
{
  assert(pc);
  char name[NAME_MAX] = { 0 };//初始化name数组(字符串)
  printf("请输入要修改人的名字:>");
  scanf("%s", name);
  int pos = FindByName(pc, name);//函数复用
  if (-1 == pos)
  {
  printf("要修改的人不存在\n");
  return;
  }
  //重新录入
  printf("请输入修改后的名字:>");
  scanf("%s", pc->data[pos].name);
  printf("请输入修改后的年龄:>");
  scanf("%d", &(pc->data[pos].age));//age不是数组,需要取地址
  printf("请输入修改后的性别:>");
  scanf("%s", pc->data[pos].sex);
  printf("请输入修改后的地址:>");
  scanf("%s", pc->data[pos].addr);
  printf("请输入修改后的电话:>");
  scanf("%s", pc->data[pos].tele);
  printf("修改完成\n");
}

2.5整理通讯录(按年龄排序)

我们分装函数SortContact实现:


void test()
{
  int input = 0;
  //创建通讯录con
  Contact con;
    //初始化通讯录
    InitContact(&con);//分装成函数实现
  do
  {
  menu();//打印菜单
  printf("请选择:>");
  scanf("%d", &input);//选择功能
  switch(input)
  {
  case 1:
            //增加联系人
            AddContact(&con);
    break;
  case 2:
            //删除联系人
            DelContact(&con);
    break;
  case 3:
            //查找联系人
            SearchContact(&con);
    break;
  case 4:
            //修改指定联系人
            ModifyContact(&con);
            break;
  case 5:
            //整理通讯录(按类型排序)
            SortContact(&con);
    break;
  case 6:
            //显示通讯录的信息
    break;
  case 0:
            //退出通讯录
    printf("通讯录已退出\n");
    break;
  default:
    printf("选择错误\n");
    break;
  }
  } while (input);
}

在contact.h中声明:


//初始化通讯录
void InitContact(Contact* pc);
//增加联系人
void AddContact(Contact* pc);
//删除联系人
void DelContact(Contact* pc);
//查找联系人
void SearchContact(const Contact* pc);
//修改指定联系人
void ModifyContact(Contact* pc);
//整理通讯录
void SortContact(Contact* pc);
在contact.c文件中实现函数功能:
//整形排序的实现
int CmpContactByAge(const void* e1, const void* e2)
{
  //这个排出来的是升序,如果想排降序,只需将e1和e2的位置调换即可
  return ((Contact*)e1)->data->age - ((Contact*)e2)->data->age;
}
//整理通讯录
void SortContact(Contact* pc)
{
  assert(pc);
  int sz = pc->sz;
  //通过qsort函数辅助排序
  qsort(pc->data, sz, sizeof(pc->data[0]), CmpContactByAge);
  printf("排序成功\n");
}


2.6查看整个通讯录

我们分装函数AddContact实现:


void test()
{
  int input = 0;
  //创建通讯录con
  Contact con;
    //初始化通讯录
    InitContact(&con);//分装成函数实现
  do
  {
  menu();//打印菜单
  printf("请选择:>");
  scanf("%d", &input);//选择功能
  switch(input)
  {
  case 1:
            //增加联系人
            AddContact(&con);
    break;
  case 2:
            //删除联系人
            DelContact(&con);
    break;
  case 3:
            //查找联系人
            SearchContact(&con);
    break;
  case 4:
            //修改指定联系人
            ModifyContact(&con);
            break;
  case 5:
            //整理通讯录(按类型排序)
            SortContact(&con);
    break;
  case 6:
            //显示通讯录的信息
            ShowContact(&con);
    break;
  case 0:
            //退出通讯录
    printf("通讯录已退出\n");
    break;
  default:
    printf("选择错误\n");
    break;
  }
  } while (input);
}


在contact.h中声明:


//初始化通讯录
void InitContact(Contact* pc);
//增加联系人
void AddContact(Contact* pc);
//删除联系人
void DelContact(Contact* pc);
//查找联系人
void SearchContact(const Contact* pc);
//修改指定联系人
void ModifyContact(Contact* pc);
//整理通讯录
void SortContact(Contact* pc);
//显示通讯录的信息
void ShowContact(const Contact* pc);


在contact.c文件中实现函数功能:


//显示通讯录的信息
void ShowContact(const Contact* pc)
{
  assert(pc);
  printf("%-10s\t%-4s\t%-5s\t%-20s\t%-12s\n", "名字", "年龄", "性别", "地址", "电话");
  int i = 0;
  for (i = 0; i < pc->sz; i++)//遍历通讯录并打印
  {
  printf("%-10s\t%-4d\t%-5s\t%-20s\t%-12s\n",
    pc->data[i].name,
      pc->data[i].age,
    pc->data[i].sex,
    pc->data[i].addr,
    pc->data[i].tele);
  }
}


这样,我们就将静态的通讯录实现成功了。


以下是源码,有兴趣的话可以拿来测试体验一下,我就不在这里演示了。


3.通讯录源码

test.c文件:

#define _CRT_SECURE_NO_WARNINGS 1
#include "contact.h"
void menu()
{
  printf("\n");
  printf("—————————— 通讯录 ———————————-\n");
  printf("—————————————————————————-\n");
  printf("————————   1.添加联系人    ————————\n");
  printf("—————————————————————————-\n");
  printf("————————   2.删除联系人    ————————\n");
  printf("—————————————————————————-\n");
  printf("————————   3.查找联系人    ————————\n");
  printf("—————————————————————————-\n");
  printf("————————   4.修改联系人信息  ———————\n");
  printf("—————————————————————————-\n");
  printf("————————   5.整理通讯录    ————————\n");
  printf("—————————————————————————-\n");
  printf("————————   6.查看整个通讯录  ———————\n");
  printf("—————————————————————————-\n");
  printf("————————   0.退出通讯录    ————————\n");
  printf("—————————————————————————-\n");
  printf("\n");
}
void test()
{
  int input = 0;
  //创建通讯录con
  Contact con;
  //初始化通讯录
  InitContact(&con);
  do
  {
  menu();
  printf("请选择:>");
  scanf("%d", &input);
  switch(input)
  {
  case ADD:
    AddContact(&con);
    break;
  case DEL:
    DelContact(&con);
    break;
  case SEARCH:
    SearchContact(&con);
    break;
  case MODIFY:
    ModifyContact(&con);
    break;
  case SORT:
    SortContact(&con);
    break;
  case SHOW:
    ShowContact(&con);
    break;
  case EXIT:
    printf("通讯录已退出\n");
    break;
  default:
    printf("选择错误\n");
    break;
  }
  } while (input);
}
int main()//主函数里不要放太多东西
{
  test();
  return 0;
}
contact.h文件:
#pragma once//防止头文件重复引用
//提前将需要使用的头文件引用,
//具体实现通讯录是,需要头文件可以直接添加
#include 
#include 
#include 
#include 
//通过#define定义的常量,方便管理和使用
#define MAX 100
#define NAME_MAX 20
#define SEX_MAX 5
#define ADDR_MAX 30
#define TELE_MAX 12
//通讯录中存放一个人的信息
typedef struct PeoInfo//typedef简化结构体名称
{
  char name[NAME_MAX];
  int age;
  char sex[SEX_MAX];
  char addr[ADDR_MAX];
  char tele[TELE_MAX];
}PeoInfo;
//创建一个结构体将数组和数组中存放的元素数封装
typedef struct Contact
{
  PeoInfo data[MAX];//data这个数组元素的类型的是结构体PeoInfo
                   //用来存放联系人信息
  int sz;//用来存放数组元素个数
}Contact;
enum Option
{
  EXIT,//0
  ADD,
  DEL,
  SEARCH,
  MODIFY,
  SORT,
  SHOW
};
//初始化通讯录
void InitContact(Contact* pc);
//增加联系人
void AddContact(Contact* pc);
//删除联系人
void DelContact(Contact* pc);
//查找联系人
void SearchContact(const Contact* pc);
//修改指定联系人
void ModifyContact(Contact* pc);
//整理通讯录
void SortContact(Contact* pc);
//显示通讯录的信息
void ShowContact(const Contact* pc);
contact.c文件:
#define _CRT_SECURE_NO_WARNINGS 1
#include "contact.h"
//初始化通讯录
void InitContact(Contact* pc)
{
  pc->sz = 0;//代表数组中有0个元素
  memset(pc->data, 0, sizeof(pc->data));//data是整个数组的大小,初始化成0
}
//增加联系人
void AddContact(Contact* pc)
{
  assert(pc);
  if (pc->sz == MAX)//如果通讯录满了
  {
  printf("通讯录已满,无法添加\n");
  return;//就会直接返回
  }
  //增加一个人的信息
  printf("请输入名字:>");
  scanf("%s", pc->data[pc->sz].name);
  //通过pc指针访问data数组的结构体类型的元素,进而访问结构体成员
  printf("请输入年龄:>");
  scanf("%d", &(pc->data[pc->sz].age));//age不是数组,需要取地址
  printf("请输入性别:>");
  scanf("%s", pc->data[pc->sz].sex);
  printf("请输入地址:>");
  scanf("%s", pc->data[pc->sz].addr);
  printf("请输入电话:>");
  scanf("%s", pc->data[pc->sz].tele);
  pc->sz++;//代表数组中的元素个数+1
}
//显示通讯录的信息
void ShowContact(const Contact* pc)
{
  assert(pc);
  printf("%-10s\t%-4s\t%-5s\t%-20s\t%-12s\n", "名字", "年龄", "性别", "地址", "电话");
  int i = 0;
  for (i = 0; i < pc->sz; i++)//遍历通讯录并打印
  {
  printf("%-10s\t%-4d\t%-5s\t%-20s\t%-12s\n",
    pc->data[i].name,
      pc->data[i].age,
    pc->data[i].sex,
    pc->data[i].addr,
    pc->data[i].tele);
  }
}
//查找函数
int FindByName(const Contact* pc, char name[])
{
  int i = 0;
  int del = 0;
  for (i = 0; i < pc->sz; i++)//遍历通讯录
  {
  if (strcmp(pc->data[i].name, name) == 0)
  {   //通过strcmp函数判断要查找的联系人是否存在
    del = i;
    return del;//返回数组下标(要查找的元素的位置)
  }
  }
  return -1;//找不到
}
//删除联系人
void DelContact(Contact* pc)
{
  assert(pc);
  char name[NAME_MAX] = { 0 };//初始化name数组(字符串)
  if (pc->sz == 0)//判断通讯录中是否存在联系人
  {
  printf("通讯录为空,无法删除\n");
  return;
  }
  //找到要删除的人
  printf("请输入要删除的人的名字:>");
  scanf("%s", name);//输入字符串
  int ret = FindByName(pc, name);//分装字符串查找函数
  if (-1 == ret)
  {
  printf("要删除的人不存在\n");
  return;
  }
  //删除
  int i = 0;
  for (i = ret; i < pc->sz - 1; i++)
  {
  pc->data[i] = pc->data[i + 1];//将存放在被删除的联系人后面的联系人信息,
    }                                 //通过循环一个个往前覆盖
  pc->sz--;//数组元素-1
  printf("删除成功\n");
}
//查找联系人
void SearchContact(const Contact* pc)
{
  assert(pc);
  char name[NAME_MAX] = { 0 };//初始化name数组(字符串)
  printf("请输入要查找人的名字:>");
  scanf("%s", name);
  int pos = FindByName(pc, name);//函数复用
  if (-1 == pos)
  {
  printf("要查找的人不存在\n");
  return;
  }
  //打印信息//我实现的是左对齐,并用水平制表符使打印出来的观感更好
  printf("%-10s\t%-4s\t%-5s\t%-20s\t%-12s\n", "名字", "年龄", "性别", "地址", "电话");
  printf("%-10s\t%-4d\t%-5s\t%-20s\t%-12s\n",
    pc->data[pos].name,
    pc->data[pos].age,
    pc->data[pos].sex,
    pc->data[pos].addr,
    pc->data[pos].tele);
}
//修改指定联系人
void ModifyContact(Contact* pc)
{
  assert(pc);
  char name[NAME_MAX] = { 0 };//初始化name数组(字符串)
  printf("请输入要修改人的名字:>");
  scanf("%s", name);
  int pos = FindByName(pc, name);//函数复用
  if (-1 == pos)
  {
  printf("要修改的人不存在\n");
  return;
  }
  //重新录入
  printf("请输入修改后的名字:>");
  scanf("%s", pc->data[pos].name);
  printf("请输入修改后的年龄:>");
  scanf("%d", &(pc->data[pos].age));//age不是数组,需要取地址
  printf("请输入修改后的性别:>");
  scanf("%s", pc->data[pos].sex);
  printf("请输入修改后的地址:>");
  scanf("%s", pc->data[pos].addr);
  printf("请输入修改后的电话:>");
  scanf("%s", pc->data[pos].tele);
  printf("修改完成\n");
}
//整形排序的实现
int CmpContactByAge(const void* e1, const void* e2)
{
  //这个排出来的是升序,如果想排降序,只需将e1和e2的位置调换即可
  return ((Contact*)e1)->data->age - ((Contact*)e2)->data->age;
}
//整理通讯录
void SortContact(Contact* pc)
{
  assert(pc);
  int sz = pc->sz;
  //通过qsort函数辅助排序
  qsort(pc->data, sz, sizeof(pc->data[0]), CmpContactByAge);
  printf("排序成功\n");
}


写在最后:

以上就是本篇文章的内容了,感谢你的阅读。


如果喜欢本文的话,欢迎点赞和评论,写下你的见解。


如果想和我一起学习编程,不妨点个关注,我们一起学习,一同成长。


之后我还会输出更多高质量内容,欢迎收看。



相关文章
|
15天前
|
程序员 C语言
【C语言】初步认识结构体
【C语言】初步认识结构体
15 0
|
16天前
|
存储 算法 程序员
C语言:基础与应用的双重魅力
C语言:基础与应用的双重魅力
|
2天前
|
存储 编译器 程序员
C语言:自定义类型 - 结构体 & 联合体 & 枚举
C语言:自定义类型 - 结构体 & 联合体 & 枚举
10 2
|
5天前
|
机器学习/深度学习 算法 数据挖掘
【C 言专栏】C 语言与机器学习的应用
【5月更文挑战第6天】C语言在机器学习中扮演关键角色,以其高效性、灵活性和可移植性实现底层算法、嵌入式系统和高性能计算。在神经网络、决策树和聚类算法等领域的实现中不可或缺。C语言被用于TensorFlow和OpenCV等知名库的底层,常与C++、Python结合使用。尽管面临开发难度和适应新算法的挑战,但C语言在机器学习领域的价值和潜力将持续展现,为科技进步贡献力量。
【C 言专栏】C 语言与机器学习的应用
|
5天前
|
存储 编译器 C语言
[C语言]自定义类型(结构体~枚举~联合体)
[C语言]自定义类型(结构体~枚举~联合体)
|
7天前
|
存储 缓存 算法
【C 言专栏】C 语言中的数据结构应用
【5月更文挑战第4天】本文探讨了C语言中的核心数据结构,包括数组、链表(单链表和双链表)、栈、队列、二叉树(如二叉搜索树和二叉堆)以及图结构。这些数据结构在程序设计中扮演着关键角色,如数组的快速访问、链表的动态管理、栈和队列的处理流程控制、树和图的复杂关系表示。理解并选择适当的数据结构可优化程序性能,而内存管理和算法优化则进一步提升效率。通过案例分析和展望未来发展趋势,本文旨在帮助读者深化对C语言数据结构的理解和应用。
【C 言专栏】C 语言中的数据结构应用
|
10天前
|
机器学习/深度学习 算法 C语言
【C言专栏】递归算法在 C 语言中的应用
【4月更文挑战第30天】本文介绍了递归算法在C语言中的应用,包括基本概念(通过调用自身解决子问题)、特点(调用自身、终止条件、栈空间)和实现步骤(定义递归函数、分解问题、设置终止条件、组合解)。文中通过阶乘计算和斐波那契数列两个案例展示了递归的使用,强调了递归可能导致的栈溢出问题及优化需求。学习递归有助于理解和应用“分而治之”策略。
|
11天前
|
存储 算法 程序员
【C言专栏】C 语言结构体的应用与实践
【4月更文挑战第30天】C语言中的结构体是自定义数据类型的关键,它组合不同类型的數據以创建新类型,尤其适合处理复杂对象如学生信息。通过定义结构体如`struct Student`,包含名字、学号和成绩,可以方便地实例化和访问成员。结构体在链表实现、函数参数传递和数组中都有广泛应用,如表示链表节点和处理批量数据。理解并熟练运用结构体对于C语言编程至关重要,能提升代码效率和可读性。
|
11天前
|
C语言
C语言进阶第八课 --------通讯录的实现
C语言进阶第八课 --------通讯录的实现
|
16天前
|
存储 算法 程序员
C语言:深入探索与实战应用
C语言:深入探索与实战应用
13 0