姓名查找程序

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;
    }

执行逻辑

  1. 遍历group数组中的每个元素
  2. 使用strcmp比较用户输入的姓名与数组中的姓名
  3. 如果找到匹配(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;
}

学习要点

  1. 结构体的使用:如何定义和初始化结构体数组
  2. 动态内存分配:malloc的使用和内存管理
  3. 字符串操作:strcmp函数的使用
  4. 指针操作:结构体指针的使用(p->name
  5. 程序逻辑:查找算法和标志位的使用
posted @ 2025-08-31 16:16  量子我梦  阅读(8)  评论(0)    收藏  举报