姓名查找程序
C语言程序详细解释
程序概述
这是一个姓名查找程序,用户输入一个姓名,程序在预定义的人员数据库中查找该姓名,如果找到就显示对应的年龄,否则显示"未找到"。
代码结构分析
1. 头文件包含
#include <stdio.h> // 标准输入输出函数(printf, gets等)
#include <string.h> // 字符串处理函数(strcmp等)
#include <stdlib.h> // 内存管理函数(malloc等)
2. 结构体定义
struct person {
char name[10]; // 姓名,最多9个字符(留1位给'\0')
int age; // 年龄
};
这定义了一个人员信息的数据结构,包含姓名和年龄两个字段。
3. 数据初始化
struct person group[6] = {
"zhang", 18,
"wang", 20,
"li", 19,
"zhao", 18,
"liu", 19
};
创建了一个包含6个人员信息的数组,存储了预定义的人员数据库。
4. 全局指针声明
struct person *p;
声明一个指向person结构体的指针,用于动态分配内存存储用户输入。
主函数执行流程
步骤1: 变量初始化
int i, flag = 0;
i
: 循环计数器flag
: 查找标志位,0表示未找到,1表示找到
步骤2: 动态内存分配
p = (struct person *)malloc(sizeof(struct person));
- 为一个person结构体分配内存空间
malloc
返回void*,需要强制转换为struct person*
- 分配的空间用于存储用户输入的信息
步骤3: 获取用户输入
gets(&p->name); // 这里有语法错误
错误分析:
p->name
本身就是char数组的首地址&p->name
是获取数组地址的地址,类型不匹配- 正确写法:
gets(p->name)
步骤4: 查找循环
for(i = 0; i < 6; i++)
if(strcmp(p->name, group[i].name) == 0)
{
printf("%d\n", group[i].age);
flag = 1;
}
执行逻辑:
- 遍历group数组中的每个元素
- 使用
strcmp
比较用户输入的姓名与数组中的姓名 - 如果找到匹配(strcmp返回0),则:
- 输出对应的年龄
- 设置flag=1表示找到了
步骤5: 结果输出
if(flag == 0)
printf("No find!\n");
如果循环结束后flag仍为0,说明没有找到匹配的姓名。
程序执行示例
示例1:找到匹配
用户输入: zhang
程序输出: 18
示例2:未找到匹配
用户输入: chen
程序输出: No find!
示例3:重复姓名
如果数组中有重复姓名,程序会输出所有匹配的年龄:
假设数组中有两个"zhang"
用户输入: zhang
程序输出: 18
22 (如果有第二个zhang年龄为22)
程序问题和改进建议
1. 安全性问题
gets()
函数不安全:不检查缓冲区边界,可能导致缓冲区溢出- 改进:使用
fgets(p->name, sizeof(p->name), stdin)
2. 内存管理问题
- 内存泄漏:分配的内存没有释放
- 改进:在程序结束前添加
free(p)
3. 错误处理
- malloc失败:没有检查malloc是否成功
- 改进:检查
p
是否为NULL
4. 输入验证
- 输入长度:没有限制输入长度,可能超出name数组大小
- 改进:添加输入长度检查
修正后的完整程序
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct person {
char name[10];
int age;
};
struct person group[6] = {
{"zhang", 18},
{"wang", 20},
{"li", 19},
{"zhao", 18},
{"liu", 19}
};
int main() // 返回类型应该是int
{
struct person *p;
int i, flag = 0;
// 检查内存分配是否成功
p = (struct person *)malloc(sizeof(struct person));
if(p == NULL) {
printf("Memory allocation failed!\n");
return -1;
}
printf("请输入姓名: ");
// 使用安全的输入函数
fgets(p->name, sizeof(p->name), stdin);
// 去除fgets可能读入的换行符
p->name[strcspn(p->name, "\n")] = '\0';
// 查找姓名
for(i = 0; i < 6; i++) {
if(strcmp(p->name, group[i].name) == 0) {
printf("年龄: %d\n", group[i].age);
flag = 1;
}
}
if(flag == 0)
printf("未找到该姓名!\n");
// 释放内存
free(p);
return 0;
}
学习要点
- 结构体的使用:如何定义和初始化结构体数组
- 动态内存分配:malloc的使用和内存管理
- 字符串操作:strcmp函数的使用
- 指针操作:结构体指针的使用(
p->name
) - 程序逻辑:查找算法和标志位的使用