模块三 · 进阶与实战 / 第 16 课
16 · 综合项目:简易通讯录
学习目标
- 综合结构体、数组、函数、字符串
- 实现添加 / 列表 / 查找
- 体会「先设计数据,再写功能」
需求
- 最多存 5 个人:姓名、电话
- 功能:添加、显示全部、按姓名查找
- 菜单循环选择,输入 0 退出
先定数据
#define MAXN 5
#define NAME_LEN 20
#define TEL_LEN 20
typedef struct
{
char name[NAME_LEN];
char tel[TEL_LEN];
} Person;
Person book[MAXN];
int count = 0;
完整参考
#include <stdio.h>
#include <string.h>
#define MAXN 5
typedef struct
{
char name[20];
char tel[20];
} Person;
Person book[MAXN];
int count = 0;
void add_person(void)
{
if (count >= MAXN)
{
printf("通讯录已满\n");
return;
}
printf("姓名: ");
scanf("%19s", book[count].name);
printf("电话: ");
scanf("%19s", book[count].tel);
count++;
printf("已添加\n");
}
void list_all(void)
{
int i;
if (count == 0)
{
printf("空\n");
return;
}
for (i = 0; i < count; i++)
{
printf("%d. %s %s\n", i + 1, book[i].name, book[i].tel);
}
}
void find_one(void)
{
char key[20];
int i;
printf("查找姓名: ");
scanf("%19s", key);
for (i = 0; i < count; i++)
{
if (strcmp(book[i].name, key) == 0)
{
printf("电话: %s\n", book[i].tel);
return;
}
}
printf("没找到\n");
}
int main(void)
{
int cmd;
for (;;)
{
printf("1添加 2列表 3查找 0退出\n");
if (scanf("%d", &cmd) != 1) break;
if (cmd == 0) break;
if (cmd == 1) add_person();
else if (cmd == 2) list_all();
else if (cmd == 3) find_one();
else printf("无效\n");
}
return 0;
}
你可以怎么扩展
- 删除联系人
- 按电话查找
- 写入文件(学文件 IO 后)
- 限制姓名/电话格式
和 Chat AI 协作
卡住时给:需求 + 你写的 20~40 行 + 现象。让它解释原因和最小改法,不要只要「完整大作业」。本课过关
必做通讯录用什么存「很多人」最合适?
逐步解析
通讯录里「一个人」是一组绑在一起的数据:姓名、电话等——这正好是结构体。而「很多人」是同类型数据的列表——这正好是数组。合起来就是结构体数组 Person book[MAXN]。若用一堆零散变量 name1,tel1,name2,tel2…,增加到 20 人时代码会爆炸,也无法用循环统一处理。选型口诀:单个对象的多个属性 → 结构体;多个同类型对象 → 数组;两者叠加就是本题答案。
必做作业
- 给项目加「按序号删除」。
- 添加前检查姓名是否重复。
- 把菜单和三个功能的调用整理得更清楚(可拆文件)。
先自己写完,再点开看解答
1:读入序号 k,从 book[k-1] 起前移,count--。
2:add 前先 strcmp 扫一遍 book,重名则拒绝。
学完去哪
恭喜学完主线。若以后要写单片机,可回头补:寄存器、位操作、中断——那是在这门 C 之上的应用层。