【C语言】通讯录的简单实现

通讯录的内容


contect.h 

#pragma once
// 包含头文件
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <stdlib.h>// 使用枚举常量定义功能
enum Function
{quit, // 注意这是逗号,不是分号save,addition,delete,search,revise,sort,show // 最后一个没有逗号
};// 人的信息
#define NAME_MAX 20
#define SEX_MAX 5
#define TELE_MAX 12
#define ADDR_MAX 30
typedef struct People_Information
{char name[NAME_MAX];int age;char sex[SEX_MAX];char tele[TELE_MAX];char addr[ADDR_MAX];
}People; // 通过typedef将struct People_Informtion定义为了People// 通讯录
#define DATA_MAX 1000
typedef struct Contact
{People data[DATA_MAX]; // data数组里面存放的是每个人的信息int sz; // 用于记录通讯录中有几个人的信息
}Contact; // 通过typedef将struct Contact定义为了Contact// 函数声明
// 初始化通讯录
void InitContact(Contact* contact);
// 增加个人信息
void AddContact(Contact* contact);
// 显示通讯录
void ShowContact(const Contact* contact);
// 删除指定信息
void DelContact(Contact* contact);
// 查找指定信息
void SeaContact(const Contact* contact);
// 修改指定联系人
void RevContact(Contact* contact);
// 排序通讯录
void SorContact(Contact* contact);

contact.c 

#define _CRT_SECURE_NO_WARNINGS
#include "contact.h"
void menu()
{printf("..............................\n");printf("....0:quit........1:save......\n");printf("....2:addition....3:delete....\n");printf("....4:search......5:revise....\n");printf("....6:sort........7:show......\n");printf("..............................\n");
}
int main()
{// 利用do{}while();循环和switch语句进行多次选择int input;// 进入main函数就要创建通讯录Contact contact; // contact就是一个通讯录// 初始化通讯录InitContact(&contact); // 将通讯录的地址传过去,不仅节省地址,而且可以通过形参改变实参do{// 有哪些功能// 通过菜单将功能展现出来menu();printf("请输入功能序号:");scanf("%d", &input);switch (input){// 通过枚举常量定义会更直观case quit:printf("退出通讯录!\n");break;case save:break;case addition:AddContact(&contact);break;case delete:DelContact(&contact);break;case search:SeaContact(&contact);break;case revise:RevContact(&contact);break;case sort:SorContact(&contact);break;case show:ShowContact(&contact);break;default:printf("无此序号,请重新输入。\n");}} while (input);return 0;
}

test.c 

#define _CRT_SECURE_NO_WARNINGS
#include "contact.h"// 初始化通讯录
void InitContact(Contact* contact)
{assert(contact);// contact->data = 0; // contact->data表示的是首元素地址// 初始化一块连续的内存空间可以使用memsetmemset(contact->data, 0, sizeof(contact->data));contact->sz = 0;
}// 增加个人信息
void AddContact(Contact* contact)
{assert(contact);// 进入函数进行判断if (contact->sz == DATA_MAX){printf("通讯录已满,无法增加个人信息!\n");return;}// 没有满则进行增加个人信息printf("请输入姓名:");scanf("%s", &(contact->data[contact->sz].name));printf("请输入年龄:");scanf("%d", &(contact->data[contact->sz].age));printf("请输入性别:");scanf("%s", &(contact->data[contact->sz].sex));printf("请输入电话:");scanf("%s", &(contact->data[contact->sz].tele));printf("请输入地址:");scanf("%s", &(contact->data[contact->sz].addr));// 增加完一条信息后sz要加1contact->sz++;printf("增加成功!\n");
}// 显示通讯录
void ShowContact(const Contact* contact)
{assert(contact);// 进入函数进行判断if (contact->sz == 0){printf("通讯录为空!\n");return;}// 显示信息// 标题printf("%-10s %-5s %-5s %-12s %-30s\n", "姓名", "年龄", "性别", "电话", "住址");for (int i = 0; i < contact->sz; i++){printf("%-10s %-5d %-5s %-12s %-30s\n",contact->data[i].name,contact->data[i].age,contact->data[i].sex,contact->data[i].tele,contact->data[i].addr);}
}// 通过名字查找联系人下标
int FindByName(const Contact* contact, char* name)
{assert(contact);for (int i = 0; i < contact->sz; i++){if (strcmp(contact->data[i].name, name) == 0){// 找到返回数组下标return i;}}return -1;
}// 删除指定信息
void DelContact(Contact* contact)
{assert(contact);char name[NAME_MAX];if (contact->sz == 0){printf("通讯录为空!\n");return;}// 通过名字查找printf("请输入要删除人的姓名:");scanf("%s", name);int ret = FindByName(contact, name);// 没找到if (ret == -1){printf("要删除的人不存在!\n");}// 找到了// 删除这个人(其实是覆盖)for (int i = ret; i < contact->sz - 2; i++) // 减2这里不是很懂{contact->data[i] = contact->data[i + 1];}contact->sz--;printf("删除成功!\n");// 最后一个直接覆盖当前这个// 结构体类型相同可以直接赋值/*contact->data[ret] = contact->data[contact->sz];contact->sz--;*/
}// 查找指定信息
void SeaContact(const Contact* contact)
{assert(contact);char name[NAME_MAX];if (contact->sz == 0){printf("通讯录为空!\n");return;}// 通过名字查找printf("请输入要修改人的姓名:");scanf("%s", name);int ret = FindByName(contact, name);// 没找到if (ret == -1){printf("要查找的人不存在!\n");}// 找到了// 显示出来printf("%-10s %-5s %-5s %-12s %-30s\n", "姓名", "年龄", "性别", "电话", "住址");printf("%-10s %-5d %-5s %-12s %-30s\n",contact->data[ret].name,contact->data[ret].age,contact->data[ret].sex,contact->data[ret].tele,contact->data[ret].addr);
}// 修改指定联系人
void RevContact(Contact* contact)
{assert(contact);char name[NAME_MAX];if (contact->sz == 0){printf("通讯录为空!\n");return;}// 通过名字修改printf("请输入要修改人的姓名:");scanf("%s", name);int ret = FindByName(contact, name);// 没找到if (ret == -1){printf("要修改的人不存在!\n");}// 找到了// 修改printf("请输入姓名:");scanf("%s", &(contact->data[contact->sz].name));printf("请输入年龄:");scanf("%d", &(contact->data[contact->sz].age));printf("请输入性别:");scanf("%s", &(contact->data[contact->sz].sex));printf("请输入电话:");scanf("%s", &(contact->data[contact->sz].tele));printf("请输入地址:");scanf("%s", &(contact->data[contact->sz].addr));printf("修改成功!\n");
}int compare_name(const void* x, const void* y)
{return strcmp((char*)x, (char*)y);
}// 排序通讯录
void SorContact(Contact* contact)
{assert(contact);if (contact->sz == 0){printf("通讯录为空!\n");return;}// 排序通讯录qsort(contact, contact->sz, sizeof(contact->data[0]), compare_name);// 显示信息// 标题printf("%-10s %-5s %-5s %-12s %-30s\n", "姓名", "年龄", "性别", "电话", "住址");for (int i = 0; i < contact->sz; i++){printf("%-10s %-5d %-5s %-12s %-30s\n",contact->data[i].name,contact->data[i].age,contact->data[i].sex,contact->data[i].tele,contact->data[i].addr);}
}

  注意:

传址还是传值

通讯录初始化涉及到传递参数,那我们到底是传址还是传值呢?

InitContact(&contact);  // 传递的是地址

// 传址:因为更节省内存空间(地址只占4/8个字节),而且可以通过形参来改变实参;

// 传值:所需的内存空间更大,并且改变形参并不会影响实参;


memset初始化连续空间

// 这里使用的是memset初始化数组,也可以通过循环将数组一个一个制成0;

memset的用法

 


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/105269.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

27 mysql 组合索引 的存储以及使用

前言 这里来看一下 mysql 中索引的 增删改查 查询在前面的系列文章中都有使用到 这里 来看一下 增删改 的相关实现 索引记录 和 数据记录 的处理方式是一致的 这里来看一下 组合索引 的相关, 以及 特性 组合索引的存储以及使用 创建数据表如下, 除了主键之外, 创建了…

Spring Boot 生成二维码

效果图 1.maven依赖 <dependency> <groupId>com.google.zxing</groupId> <artifactId>javase</artifactId>

光电柴微电网日前调度报告

摘要 微电网是目前国内外应用较为广泛的一种绿色可再生能源&#xff0c;近几年我国微电网产业的发展十分迅速。然后&#xff0c;越来越多的微电网系统建立并网&#xff0c;微电网产生的电能受外界因素影响较大&#xff0c;具有一定的随机性和波动性&#xff0c;给并网后的电力系…

Sketch macOS 支持m1 m2 Sketch 2023最新中文版

SketchUp Pro 2023是一款功能强大的三维建模软件&#xff0c;适用于建筑设计师、室内设计师、工程师和其他创意专业人士。以下是SketchUp Pro 2023的一些主要特点和功能&#xff1a; 三维建模&#xff1a;SketchUp Pro 2023允许用户以直观的方式创建三维模型。通过简单的绘图工…

Swagger使用

Swagger 简介 号称世界上最流行的API框架&#xff1b;Restful API 文档在线生成工具 —> API文档与API定义同步更新直接运行&#xff0c;可以在线测试 API 接口&#xff1b;支持各种语言&#xff1b;&#xff08;Java&#xff0c;PHP…&#xff09; 官网 Spring Boot 集…

实施 DevSecOps 最佳实践

DevSecOps 是一个框架&#xff0c;它将开发 (Dev)、IT 运营 (Ops) 和安全 (Sec) 流程的实践融合到一个简化的流程中。使用这种方法&#xff0c;DevSecOps 团队能够确保将安全性集成到软件开发生命周期中&#xff0c;确保以“安全第一”的心态构建、部署和维护软件。在本教程中&…

【QT】Ubuntu 搭建 QT 环境(图形化界面安装)

介于直接使用源码编译安装 QT 耗时较长&#xff0c;而且需要手动编写脚本进行编译&#xff0c;难度较大&#xff0c;这里选择直接以图形化界面的方式安装 QT 。 目录 1、下载 QT 安装包 2、安装 QT 3、添加环境变量 4、cmake 引入 QT 库 5、Failed to find “GL/gl.h“ in…

采用 guidance 提高大模型输出的可靠性和稳定性

本文首发于博客 LLM 应用开发实践 在复杂的 LLM 应用开发中&#xff0c;特别涉及流程编排和多次 LLM 调用时&#xff0c;每次的 Prompt 设计都取决于前一个步骤的大模型输出。如何避免大语言模型的"胡说八道"&#xff0c;以提高大语言模型输出的可靠性和稳定性&#…

[python] pytest

在写一个项目前, 可以先编写测试模块 测试模块中包含了一个个最小的功能 当每一个功能都完善正确时 再将这些功能转换成项目运行的功能 多个项目运行的功能就组成了一个模块 多个模块就组成了一个项目服务 pytest 是一个 Python 测试框架&#xff0c;它提供了简单易用的语…

竞赛选题 深度学习YOLOv5车辆颜色识别检测 - python opencv

文章目录 1 前言2 实现效果3 CNN卷积神经网络4 Yolov56 数据集处理及模型训练5 最后 1 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; **基于深度学习YOLOv5车辆颜色识别检测 ** 该项目较为新颖&#xff0c;适合作为竞赛课题方向&#xff0…

React如何优化减少组件间的重新Render

目前写了不少React的项目&#xff0c;发现React有些特点更灵活和注重细节&#xff0c;很多东西需要有一定的内功才能掌握好&#xff1b;比如在项目中常常遇到的组件重复渲染&#xff0c;有时候组件重复渲染如果内容是纯文本&#xff0c;不打印日志就不容易发现重复渲染了&#…

每日一题 136. 只出现一次的数字(简单,位运算)

异或运算性质&#xff0c;两个相等的数作异或运算得零&#xff0c;任何数与零作异或运算保持不变 所以整个数组的异或和就是答案 class Solution:def singleNumber(self, nums: List[int]) -> int:ans 0for i in nums:ans ^ ireturn ans一行代码&#xff0c;reduce作累积操…

亚马逊测评安全吗?

测评可以说是卖家非常宝贵的财富&#xff0c;通过测评和广告相结合&#xff0c;可以快速有效的提升店铺的产品销量&#xff0c;提高转化&#xff0c;提升listing权重&#xff0c;但现在很多卖家找真人测评补单后店铺出现问题导致大家对测评的安全性感到担忧&#xff0c;因为真人…

List 模拟实现

前言 本文将会向你介绍如何模拟实现list、iterator迭代器 模拟实现 引入 迭代器是一种用于访问容器中元素的对象&#xff0c;它封装了对容器中元素的访问方式。迭代器提供了一组操作接口&#xff0c;可以让我们通过迭代器对象来遍历容器中的元素。&#xff08;iterator迭代器…

Lua调用C#类

先创建一个Main脚本作为主入口&#xff0c;挂载到摄像机上 public class Main : MonoBehaviour {// Start is called before the first frame updatevoid Start(){LuaMgr.GetInstance().Init();LuaMgr.GetInstance().DoLuaFile("Main");}// Update is called once p…

关于SpringBoot2.x集成SpringSecurity+JJWT(0.7.0-->0.11.5)生成Token登录鉴权的问题

项目场景&#xff1a; 问题&#xff1a;遵循版本稳定的前提下&#xff0c;搭建权限认证框架&#xff0c;基于SpringBoot2.xSpringSecurity向上依赖jjwt0.7.0构建用户认证鉴权&#xff0c;起因是某L觉得jjwt0.7.0版本&#xff0c;官方已经放弃维护&#xff0c;且从maven仓库对0…

python二次开发CATIA:测量曲线长度

以下代码是使用Python语言通过win32com库来控制CATIA应用程序的一个示例。主要步骤包括创建一个新的Part文件&#xff0c;然后在其中创建一个新的几何图形集&#xff0c;并在这个集合中创建一个样条线。这个样条线是通过一组给定的坐标点来创建的&#xff0c;这些点被添加到集合…

SpringCloud-Config

一、介绍 &#xff08;1&#xff09;服务注册中心 &#xff08;2&#xff09;管理各个服务上的application.yml&#xff0c;支持动态修改&#xff0c;但不会影响客户端配置 &#xff08;3&#xff09;一般将application.yml文件放在git上&#xff0c;客户端通过http/https方式…

MyLife - Docker安装rabbitmq

Docker安装rabbitmq 个人觉得像rabbitmq之类的基础设施在线上环境直接物理机安装使用可能会好些。但是在开发测试环境用docker容器还是比较方便的。这里学习下docker安装rabbitmq使用。 1. rabbitmq 镜像库地址 rabbitmq 镜像库地址&#xff1a;https://hub.docker.com/_/rabbi…

介绍一款小巧的Excel比对工具-DiffExcel

【缘起&#xff1a;此前找了一通&#xff0c;没有找到免费又好用的Excel比对工具&#xff0c;而ExcelBDD需要把Excel文件存放到Git&#xff0c;因此迫切需要Excel比对工具。 最新升级到V1.3.3&#xff0c;因为git diff有变化&#xff0c;原来是git diff会修改文件名&#xff0…