题目:
计算年龄
【教学目标】
关键词:指针,字符串
知识和能力目标:
能够熟练、规范使用流程图描述算法。熟练使用数组、循环结构进行排序操作。理解冒泡排序的方法,并能编程实现。能够选用优化的冒泡排序算法。
价值目标:
工程素质:信息编码(Information Coding)是指在进行信息处理时,赋予信息元素以代码的过程,其目的是为了方便信息的存储、检索和使用。信息编码的基本原则是在逻辑上满足使用者的要求,又适合于处理的需要。编码的结构应易于理解和掌握,编码还应有广泛的适用性,易于扩充。
【问题描述】
中国国家质量技术监督局于1999年实施的GB11643-1999《公民身份号码》中明确规定了18位身份证标准。其中,前6位为地址码;第7至14位为出生日期码;第15至17位为顺序码,第18位为校验码。校验码是根据前面17位数字码,按照ISO7064:1983.MOD11-2校验码计算得到,其取值范围是0至10。其中,10用罗马数字符X表示。
【问题说明】
(1) 本问题中,计算年龄的对应时间不确定。
(2) 请自行编写主程序验证函数,输出格式不限。
【实验结果】
1. 请编写实验《课程报告》,格式见附件一。
2. 讨论一下。
请在《课程报告》中回应以下问题。
(1) 我国的身份证编码是如何体现了广泛适用性特点的?请简述你的看法。
(2) 教师提出的其他问题。
课程报告:
计算年龄
0 题目
计算年龄问题
1 问题描述
本问题要求从键盘输入一个身份证号码(存在罗马数字X),并根据当前日期来计算此人是否成年。
2 问题分析
输入:已知身份证号码中第7至14位为出生日期码且可能存在罗马数字X,因此可用字符串存储。
输入数据描述:char input[19];
输出:字符串:”此人已成年\n”/”此人未成年\n”
3. 实验结果记录
实验数据共六组:成年人的身份证号,未成年人的身份证号,存在罗马数字X的身份证号,并有意测试边界条件。
(1)测试数据1
(2)测试数据2
(3)测试数据3
(4)测试数据4
(5)测试数据5
(6)测试数据6
4 实验分析及结论
4.1 实验心得
经过反复测试和调试,最终达到了问题要求。总结本次实验中遇到的问题,主要有三方面。
(1)从身份证中提取目标信息方法不适宜
编码时尝试使用for循环来提取身份证中的出生年月日信息,但发现需要添加很多条件判断语句,使得代码逻辑复杂,更为臃肿,效率低下。
修改:因为身份证上的出生日期位置确定,可以直接使用字符数组的下表访问元素并使用,故修改为:
2)条件判断表达式书写错误
测试时发现相等运算符”==”错误书写为赋值运算符”=”。将if (time[1] = month)修改为if (time[1] == month)
(3)需要注意日期的边界问题
本次编码时特地注意了对边界条件的判断,在修改完语法上的错误和编码时的误操作后,并未发现逻辑上的遗漏。如测试数据1:2000年1月1日出生的人在2018年1月1日刚好成年,程序成功判断为成年人。但是在今后的编码时仍当注意检查对边界条件的判断。
4.2 实验结论
本实验是对当前日期和身份证上的出生日期进行运算,判断身份证持有人是否成年。从6组测试数据的结果看,程序符合预期,全部测试结果均符合题目要求。本题采用了字符串存储身份证号,并在后续的程序中进行数据提取。但实际上由于输入的身份证号并不存在空格,可以使用scanf与for语句在输入的时候直接提取,不使用字符串数组,可以节省更多空间。在后续学习过程中,将进一步对各种输入和数据处理方式进行研究和比较。
5 讨论一下
回应案例的“讨论一下”中的问题。
(1) 我国的身份证编码是如何体现了广泛适用性特点的?请简述你的看法。
通过前6位表示出生地区,中间8位表示出生日期,不仅表明了身份证持有人的部分基本信息,还是一种生成身份证编码的一种限定条件:在前两种信息的限制下,后4位编码在罗马数字X的帮助下,完全可以表示同一地区一天的所有新生儿的编号,并表明该新生儿的性别。因此我国省份证编码具有广泛适用性的特点。
(2) 教师提出的其他问题。
希望老师不会发现我自己引用自己发的贴子还把题目变复杂了。
6 程序代码
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#define gets gets_s
int main()
{
char input[19] = { 0 };
int time[3],judge=0;
printf("请以a b c的形式输入当前的年月日(例:2000年1月1日:输入\"2000 1 1\")\n当前日期: ");
scanf("%d%d%d", &time[0], &time[1], &time[2]);
printf("身份证号码: ");
rewind(stdin);
gets(input,19);
int year,month,day;
year = (input[6] - '0') * 1000 + (input[7] - '0') * 100 + (input[8] - '0') * 10 + (input[9] - '0');
month = (input[10] - '0') * 10 + (input[11] - '0');
day = (input[12] - '0') * 10 + (input[13] - '0');
if (time[0] - year > 18)
judge = 1;
if (time[0] - year == 18)
{
if (time[1] > month)
judge = 1;
if (time[1] == month)
if (time[2] >= day)
judge = 1;
}
if (judge)
printf("输出:此人已成年\n");
else
printf("输出:此人未成年\n");
return 0;
}